Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 411
soleil Avatar asked Jul 20 '14 17:07

soleil


2 Answers

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 {
    // ...
  }
}
like image 178
GoZoner Avatar answered Nov 15 '22 14:11

GoZoner


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.

like image 20
matt Avatar answered Nov 15 '22 12:11

matt