By Casey Liss

In my new gig, my first assignment has been to work on a proof-of-concept app that demonstrates a new architecture we’re considering. (If you care, a combination of VIPER and RxSwift.)

This new app is written entirely in Swift. I’m new to Swift.

Taking inspiration from Brent Simmons’s Swift Diary, there are a few things about Swift that are deserving of praise and I plan to call out as I’m learning the language.

Today’s case study: Enumerations.


Enumerations are not a new construct; they’ve been in most languages I’ve worked with. Generally speaking, they look something like this, in most C-derived languages:

enum LibraryBookState {
    CheckedIn,
    CheckedOut
}

Think of it as saying “For a library book, it can either be CheckedIn or CheckedOut. Nothing else.”

As with life, things are rarely that simple.

In this contrived example, it’s useful to know that the library book is checked out to someone, but to whom? We’d need another variable to track the patron the book is checked out to. So, if we were designing a Book class in Swift, it may look like this:

class Book {
    var status: LibraryBookState
    var checkedOutTo: Patron?
    var title: String
    var author: String
}

That’s a little, well, weird, if you think about it. The patron the book is checked out to is really part of the state of the book. A part of the state that we’re capturing in the LibraryBookState enumeration.

Wouldn’t it be nice if we could keep track of who the book is checked out to within the LibraryBookState enumeration?


In Swift, we can. All thanks to associated values.

We can write a Swift version of our enumeration like so:

enum LibraryBookState {
    case CheckedIn
    case CheckedOut(patron: Patron)
}

Note the change in CheckedOut: now it looks like a function call. Though syntactically a little curious, CheckedOut is still just an enumeration value. However, it has a super power: it carries with it an associated value.

The only way to set a variable to the CheckedOut enumeration value is to also provide the associated Patron along with it.

let casey = Patron(name: "Casey Liss")
var state = .CheckedOut(patron: casey)

Similarly, when we are using a switch to evaluate the value of that enumeration, we can get the value back out:

switch state {
case .CheckedIn:
    // ...
case .CheckedOut(let p):
    // p is the associated Patron
}

Associated values are a perfect solution to a problem I didn’t know I had. To return to our Book class, we can now simplify it:

class Book {
    var status: LibraryBookState
    var title: String
    var author: String
}

We no longer need checkedOutTo since we’re capturing that within LibraryBookState. The revised class is much cleaner, and more directly represents the way we wish to model a book.


I’ve found associated values are used very frequently for the results of network requests. Many take a form like this:

enum FetchBookResult {
    case .Success(book: Book)
    case .Failure(error: ErrorType)
}

Using enumerations in this way makes it so much easier to return a value from a function, as you don’t have to do any awkward dancing with tuples or multiple callbacks or equivalent:

func fetchBook(id: Int) -> FetchBookResult {
    // ...
}

Enumerations in Swift have many other tricks as well:

  • Properties
  • Methods
  • Extensions
  • Protocols (think interfaces)

It’s stunning how powerful support for these paradigms makes enumerations.

I’m only three weeks in, but so far Swift is really impressing me. It’s bringing a joy to development that I haven’t felt in quite some time. I often feel like I’m fighting my own ignorance; I rarely feel as though I’m fighting the language.

There’s a lot in flux with Swift these days, which makes many people I deeply respect shy away from it. That may come to burn us, if we try to go all-in on Swift; especially once Swift 3 comes along. However, I’m very hopeful and excited for the future, as it’s clear Swift is a language that is somehow able to be both well-considered and improving rapidly.