Swift Enum Cheatsheet

In Objective-C enums (Enumerated type) define grouped constants for fixed values. These could be days of the week, styles, types, modes, etc.

To refresh your memory here is a typical enum in Objective-C:

typedef NS_ENUM(NSInteger, UITableViewCellStyle) {  
    UITableViewCellStyleDefault,
    UITableViewCellStyleValue1,
    UITableViewCellStyleValue2,
    UITableViewCellStyleSubtitle
};

Read more about Objective-C enums in this great NSHipster article or here.

In Swift, enums are more advanced than they are in Objective-C. Here is a short cheat sheet for enums in Swift.

Enum Basics

How to define a simple enum:

enum SomeOptionOrStuffThatYouThinkGoesInEnums {  
    case SomeOptionOne
    case SomeOptionTwo
    case SomeOptionThree
}

Enums can also be defined in one line:

enum SomeOptionOrStuffThatYouThinkGoesInEnums {  
    case SomeOptionOne, SomeOptionTwo, SomeOptionThree
}

Don't worry about default values, you don't have to declare them like you do in Objective-C. Note that for the enums you defined without a default value, Objective-C was already assigning values for you under-the-hood, 0,1,2, etc. But in Swift they are not assigned a default integer value when they are created, they are full-fledged values in their own right, with an explicitly-defined respective type.

If you want, you can assign a value for an initial enum and Swift will auto-increment it for you:

enum SomeOptionOrStuffThatYouThinkGoesInEnums {  
    case SomeOptionOne = 1, SomeOptionTwo, SomeOptionThree
}

In this case SomeOptionTwo will be 2 and SomeOptionThree will be 3 and so on. These are so-called "Raw Values" (we are going to take a look at them later in this article).

Dot syntax:

You can call enums .SomeOptionOne, .SomeOptionTwo, etc. if the compiler can infer that the value you're referring to is of that enum type.

An example:

var anOption = .SomeOptionOne // this is exactly the same as var anOption = SomeOptionOrStuffThatYouThinkGoesInEnums.SomeOptionOne

switch anOption {  
    case .SomeOptionOne:
        doStuff()
    case .SomeOptionTwo:
        doOtherStuff()
    case .SomeOptionThree:
        doSomethingElse()
    default:
        break
}

Associated Values

This is the most interesting enum feature in Swift. You can associate, attach, or add arbitrary data to your enums when you create them, and you can store them in variables. Here is an example:

enum SomeTypeThatCanHaveStuffStashedInIt {  
    case StuffTypeOne(Int, String)
    case StuffTypeTwo(String)
    case StuffTypeThree
}

var stuffOne = SomeTypeThatCanHaveStuffStashedInIt.StuffTypeOne(1, "blah")  
var stuffTwo = SomeTypeThatCanHaveStuffStashedInIt.StuffTypeTwo("blah again")  
var stuffThree = SomeTypeThatCanHaveStuffStashedInIt.StuffTypeThree

You can use them like this in a switch case:

switch stuffOne {  
    case let .StuffTypeOne(integerValue, stringValue):
        print("integer value = /(integerValue), string value = /(stringValue)")
    case .StuffTypeTwo(var stringValue):
        print("string value = /(stringValue) only")   
    case .StuffTypeThree:
        print("and the other thing here")
    default:
        break
}

As you can see you can access integerValue and stringValue as constants in the case statement (notice that let is outside of the parentheses). Alternatively you can put var or let in front of each value definition inside of the parentheses (like stringValue in case two).

Raw Values

Raw values are enums that have predefined values upon declaration. Keep in mind though that Apple documentaion says that raw values are not the same as associated values:

Raw values are set to prepopulated values when you first define the enumeration in your code. The raw value for a particular enumeration member is always the same. Associated values are set when you create a new constant or variable based on one of the enumeration’s members, and can be different each time you do so.

enum EscapeCharacter: Character {  
    case Tab = "\t"
    case NewLine = "\n"
    case Return = "\r"
}

Raw values can be strings, characters, or any of the integer or floating-point number types. Or they can be auto-incremented as in the example above

To access raw values you use .toRaw() and to find an enum with a specified raw value you call .fromRaw(value):

let tab = EscapeCharacter.Tab.toRaw()

let newlineEnum = EscapeCharacter.fromRaw("\n")

How to make it work with Objective-C

Take a look at this Apple Doc. It states that you can't use Swift enums (among other things) in Objective-C.

Also here Apple says:

Swift imports as a Swift enumeration any C-style enumeration marked with the NS_ENUM macro. This means that the prefixes to enumeration value names are truncated when they are imported into Swift, whether they’re defined in system frameworks or in custom code.

This means it's a one way street - you can use Objective-C enums in Swift but not the other way around.

But as of Swift version 1.2 (Xcode 6.3) you can now use the @objc prefix:

@objc enum Bear: Int {
    case Black, Grizzly, Polar
}

Observation (KVO):

KVO only works with NSObject subclasses in Swift. You can't observe enums unless they are understood by Objective-C, which means they have to be of Int type. The property that holds them should be prefixed with dynamic operator.

enum EscapeCharacter: Int {  
    case Tab = 1
    case NewLine = 2
    case Return = 3
}

dynamic var someObservableProperty: Int = EscapeCharacter.Tab.rawValue  

Conclusion

As you can see Swift enums are more advanced than Objective-C enums and they give you a lot more features compared to the typedef style enums we used before.

If you have any questions about enums or Swift in general feel free to leave a comment below or shoot us an email at info@smartcloud.io, we'd be happy to help you.

__
Alex Bush @alexvbush.
Editor: Tim Baron.


If want to learn more about Swift you can checkout our Grokking Swift Series

comments powered by Disqus