3

I have a question about enum in Swift. I declared my enum like this:

enum FirstEnum : CustomStringConvertible {
    case VALUE1
    case VALUE2
    case VALUE3

    var description: String {
        switch self {
            case .VALUE1:
                return "First value"
            case .VALUE2:
                return "Second value"
            case .VALUE3:
                return "Third value"
        }
    }

    func getFromCode(value:String) -> FirstEnum? {
        switch value {
            case "v1":
                return FirstEnum.VALUE1
            case "v2":
                return FirstEnum.VALUE2
            case "v3" :
                return FirstEnum.VALUE3
        }
    }

I need to get enum from a string (like a dictionary) so I expect this line should work:

let foo = FirstEnum.getFromCode("v1") 

But XCode (7) expects a FirstEnum parameter for method getFromCode instead a String as declared in method definition, saying:

Cannot convert value of type "String" to expected argument type "FirstEnum"

Why this?...what I'm doing wrong?

3 Answers 3

5

Use Failable Initializers for Enumerations

You can use a failable initializer to select an appropriate enumeration member based on one or more parameters. The initializer can then fail if the provided parameters do not match an appropriate enumeration member.

The example below defines an enumeration called TemperatureUnit, with three possible states (Kelvin, Celsius, and Fahrenheit). A failable initializer is used to find an appropriate enumeration member for a Character value representing a temperature symbol:

enum TemperatureUnit {
    case Kelvin, Celsius, Fahrenheit
    init?(symbol: Character) {
        switch symbol {
        case "K":
            self = .Kelvin
        case "C":
            self = .Celsius
        case "F":
            self = .Fahrenheit
        default:
            return nil
        }
    }
}
Sign up to request clarification or add additional context in comments.

Comments

4

In Swift, you can derive your enum from String.

enum FirstEnum : String {
    case VALUE1 = "First value"
    case VALUE2 = "Second value"
    case VALUE3 = "Third value"

    static func getFromCode(value:String) -> FirstEnum? {
        switch value {
        case "v1":
            return FirstEnum.VALUE1
        case "v2":
            return FirstEnum.VALUE2
        case "v3" :
            return FirstEnum.VALUE3
        default:
            return nil
        }
    }
}

Also, your getFromCode method should be static and needs a default clause.

But you don't need this method when you derive from String. To construct your enum value , you can use the rawValue like following:

let value = FirstEnum(rawValue: "First value")

Comments

3

You need a static func so that you can call it without an instance of the enum:

static func getFromCode(value:String) -> FirstEnum? {
    switch value {
    case "v1":
        return FirstEnum.VALUE1
    case "v2":
        return FirstEnum.VALUE2
    case "v3" :
        return FirstEnum.VALUE3
    default:
        return nil
    }
}

You were getting the error because there is a hidden parameter when calling a method that is the instance of the enum. Admittedly, the error message could be better.

Without static, you need an instance of the enum to call it. Note that this works with the function as you had it defined:

let foo = FirstEnum.VALUE3.getFromCode("v1")

Also, your switch needs to be exhaustive, which is why I added the default case.

2 Comments

ops..I forgot static keyword! Thanks, now it works like a charm!
I think this is not the best solution. Look at Failable Initializers for Enumerations below

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.