Enums | Swift Basics

Swift basics 002

A standard feature of most programming languages is enumerations, allowing you to define a group of related items.

Basics

In its simplest form, the structure of an enum is its name (defined similarly to a class name), and multiple case statements inside the body of the enum:

enum CaptainAmericaMovie {
 case theFirstAvenger
 case theWinterSoldier
 case civilWar
}

Unlike NS_ENUM in Objective-C, Swift enums don't have an integer value (or any other value) by default although it's very easy to enable this functionality with raw values.

Raw Values

If you want your enum cases to have integer values, you just need to add the type as the first item in the inheritance list (the same as defining the super class or protocol conformance):

enum CaptainAmericaMovie: Int {
 ...
}

With this change, each case is assigned an integer raw value, starting at 0 and incrementing by 1 for each case. If you don't want the raw values to start at 0, you can give the first case another value and each case will increment from there. You can of course give each case an explicit value.

enum CaptainAmericaMovie: Int {
 case theFirstAvenger = 1
 case theWinterSoldier
 case civilWar
}

Another option is to give each case a String raw value. By default, the raw value will be the case.

enum AvengersMovie: String {
 case assemble
 case ageOfUltron
 case infinityWar
 case endgame
}

print(AvengersMovie.assemble.rawValue) // prints "assemble"

You may however want to give them better values:

enum AvengersMovie: String {
 case assemble = "Avengers: Assemble"
 case ageOfUltron = "Avengers: Age of Ultron"
 case infinityWar = "Avengers: Infinity War"
 case endgame = "Avengers: Endgame"
}

print(AvengersMovie.assemble.rawValue) // prints "Avengers: Assemble"

Associated Values

Another feature of enums is the ability to define associated values. Each case can have different associated values, and they can be named or not

enum Result {
 case success(String)
 case failure(Error)
}
let var1 = Result.success("string")

enum ResultWithNamedValues {
 case success(result: String)
 case failure(error: Error)
}
let var2 = ResultWithNamedValues.success(result: "string")

When switching over the enum, there are 2 different syntaxes for capturing the associated values - either put the let before each value as in the first example, or put it once after the case keyword as in the second example:

enum Media {
 case book(title: String, author: String)
 case film(title: String, director: String)
}

let item: Media = ...
switch item {
case .book(let title, let author):
 print("\(title) written by \(author)")
case .film(let title, let director):
 print("\(title) directed by \(director)")
}

switch item {
case let .book(title, author):
 print("\(title) written by \(author)")
case let .film(title, director):
 print("\(title) directed by \(director)")
}

You don't have to capture all, or any, of the associated values if you don't want to.

switch item {
case .book(let title, _):
 print("\(title)")
case .film:
 print("A film")
}
the Swift logo on a yellow background iOS
How to Filter, Map, and Reduce in Swift

These are some of the common ways of working with arrays.

Read

Looking for something else?

Search over 400 blog posts from our team

Want to hear more?

Subscribe to our monthly digest of blogs to stay in the loop and come with us on our journey to make things better!