In this post, I'm going to demonstrate some of the powerful new features of enumerations in Swift.
Declaring Swift Enumerations
Just about every programming language has the concept of enumerations. An enumeration allows you to group a set of related constants together. It contains a complete list of all the possible values for a given type.
In Swift, you declare a simple enumeration as follows:
This enumeration contains a complete list of all the functions available on a very simple calculator. Each case keyword declares a separate member of the enumeration.
You can also declare an enumeration using a single case and list the members of the enumeration separated by commas as shown here:
Unlike enumerations in Objective-C, the members of a Swift enumeration are not automatically assigned an integer value. Each member is a full-fledged value of the enumeration.
You reference the values of an enumeration by specifying the enumeration type, followed by a period, and then the enumeration member as shown here (I specified the type of the currentOperation variable to reinforce that it is the type of the enumeration—CalculatorOperation):
This is different than Objective-C where you only reference the member name (i.e. UITableViewCellAccessoryCheckMark). I prefer the new Swift syntax since it clearly demonstrates that the members are part of the same enumeration. In fact, when you type the name of the enumeration and type a period, Code Completion pops up a list of members to choose from.
Once the type of a variable is declared to be of a particular enumeration, you can use a shortened dot syntax for accessing members. This is particularly useful in switch statements as shown here:
Enumeration Raw Values
At times, you may want to associate a value with each member of an enumeration. For example, in Objective-C it's common to create associated string values for enumeration members by creating a wrapper class for the enumeration. This is a bit of a kludge, but it works.
Fortunately, in Swift, this functionality is built into enumerations in the form of raw values. For example, the following enumeration declares an associated string value for each member of the enumeration:
When declaring raw values for an enumeration, you add a colon after the enumeration name followed by the type of the associated raw values (they must all be of the same type.) Then you specify the raw value for each member in the enumeration.
Here are some rules governing raw values:
- All raw values must be of the same type
- Raw values can be strings, characters, or any integer or floating point number type
- Within an enumeration, each raw value must be unique
- Integer raw values auto-increment if no value is specified for some of the enumeration members.
You can access the raw value of an enumeration member by calling its toRaw() method. For example:
This method accepts a parameter of type DeviceFamily and accesses the raw String value by calling the toRaw() method on the DeviceFamily member. So, for example, if DeviceFamily.AppleTV is passed tothis method, the call to the toRaw() method will store the string "Apple TV" in the familyName variable.
Conversely, you can use an enumeration's fromRaw() method to retrieve the enumeration member for a particular raw value as shown here:
The question mark after DeviceFamily is Swift's way of indicating that the value of the DeviceFamily variable may be null. This is so because the fromRaw() method may not find a matching enumeration member.
Enumeration Associated Values
In Swift, enumerations also have an advanced feature that allows you to store associated values with enumeration members. This is similar in concept, but different from raw values.
For example, the following code declares a UniqueIdentifier enumeration that has UUID and AutoIncrement members:
The UUID member can have an associated String value and the AutoIncrement member can have an associated Int value. This enumeration might be used in a situation where you are creating a bridge between two different apps—one app that stores unique identifiers as UUID values and one that stores unique identifiers as integers.
Note that the UniqueIdentifier enumeration declaration doesn't set the value of each member as you do when you specify raw values. Rather, it simply declares the type of the value associated with each member.
You can declare a variable to be of type UniqueIdentifier and then store either an Int or UUID value in the variable. For example:
You can use a switch statement to get the value of a UniqueIdentifier variable as shown here:
In a switch statement, you can extract each associated value as a variable using the var prefix or as a constant using the let prefix as shown above.
It's great to see these powerful, more modern features in Swift. Ultimately, these tools help bulletproof your code and make writing your iOS apps even easier.