soleil
soleil

Reputation: 13135

Swift - using enum in switch statement

I get this error:

'NSNumber' is not a subtype of Cat

Here is the code:

enum Cat:Int {
    case Siamese = 0
    case Tabby
    case Fluffy
}

let cat = indexPath.row as Cat
    switch cat {
    case .Siamese:
        //do something
        break;
    case .Tabby:
        //do something else
        break;
    case .Fluffy:

        break;
    }

How can I resolve this error?

Upvotes: 5

Views: 5940

Answers (2)

matt
matt

Reputation: 536027

The way I handled this same kind of situation in a recent app was to use a Struct consisting entirely of static members, instead of an Enum - in part because I had more information to associate with each option, in part because I got sick of having to call toRaw() and fromRaw() everyplace, and in part because (as your example shows you've discovered) an Enum loses its advantage when it turns out that you can't cycle through, or get a complete list of, the cases.

So, what I did was this:

struct Sizes {
    static let Easy = "Easy"
    static let Normal = "Normal"
    static let Hard = "Hard"
    static func sizes () -> [String] {
        return [Easy, Normal, Hard]
    }
    static func boardSize (s:String) -> (Int,Int) {
        let d = [
            Easy:(12,7),
            Normal:(14,8),
            Hard:(16,9)
        ]
        return d[s]!
    }
}

struct Styles {
    static let Animals = "Animals"
    static let Snacks = "Snacks"
    static func styles () -> [String] {
        return [Animals, Snacks]
    }
    static func pieces (s:String) -> (Int,Int) {
        let d = [
            Animals:(11,110),
            Snacks:(21,210)
        ]
        return d[s]!
    }
}

Now when we get to cellForRowAtIndexPath I can talk like this:

    let section = indexPath.section
    let row = indexPath.row
    switch section {
    case 0:
        cell.textLabel.text = Sizes.sizes()[row]
    case 1:
        cell.textLabel.text = Styles.styles()[row]
    default:
        cell.textLabel.text = "" // throwaway
    }

Essentially I've just used the two Structs as namespaces with some added intelligence. I'm not saying this is better than what you're doing; they are both eminently Swifty. It's just another idea to consider.

Upvotes: 3

GoZoner
GoZoner

Reputation: 70245

Use Cat.fromRaw(indexPath.row) to get the enumeration.

Because the return value of fromRaw() is an optional, use it like thus:

if let cat = Cat.fromRaw (indexPath.row) {
  switch cat {
    // ...
  }
}

Upvotes: 10

Related Questions