Swift Programming – Enumerations

In this tutorial you’ll learn about enumerations in Swift. To follow along, it is recommended to have a Mac and the Xcode IDE installed on it. This tutorial makes use of the Xcode playground for compilation of the Swift codes. If you do not have a Mac, you may try using the open-source code editors which support different operating systems such as AtomSublimeText or VSCode.

Enumerations

Enumerations are used to group related values with a common type. You define an enumeration using the keyword enum. It is a convention to name your enums using the camelcase starting with a capital letter and to use the word in singular. For example, let’s say we want to define an enum with days of the week.

enum DayOfWeek {
    case monday
    case tuesday
    case wednesday
    case thursday
    case friday
    case saturday
    case sunday
}

Instead of writing the enumeration cases (Monday, Tuesday, Wednesday…) on separate lines, we can write them on a single line.

enum MonthOfYear {
    case january, february, march, april, may, june, july, august, september, october, november, december
}

var month = MonthOfYear.september
month = .october

Notice how we assigned a new value to the variable month using just a dot and the value.

Matching Enumeration Values with a Switch Statement

We can use a switch statement to match the enumeration values.

switch month {
case .december:
    print("This year is ending pretty soon")
default:
    print("We still got some months before new year")
}

Iterating over Enumeration Cases

If you want to have a collection of the cases of an enumeration, you can do so by writing : CaseIterable after the enum‘s name.

enum Supermarket : CaseIterable {
    case intermart, jumbo, winners
}

let supermarkets = Supermarket.allCases

for supermarket in supermarkets {
    print(supermarket)
}

Associated Values

You can store values of other types alongside the case values.

enum PaymentMethod {
    case cash
    case bank(String)
}

var paymentMethod = PaymentMethod.cash
print(paymentMethod)
paymentMethod = .bank("00002345789")
print(paymentMethod)

You can extract the associated values using a constant or a variable in a switch statement.

switch paymentMethod {
case .cash:
    print("No value")
case .bank(let accountNumber):
    print("Bank Account Number: \(accountNumber)")
}

If all the associated values will be a constant or a variable, you can place the let or var before the enumeration case values.

paymentMethod = .cash

switch paymentMethod {
case .cash:
    print("No value")
case let .bank(accountNumber):
    print("Bank Account Number: \(accountNumber)")
}

Raw Values

You can provide a raw value as an alternative to associated values. For example, let’s say you want to get an Int from an enumeration value.

enum DayNumber: Int {
    case monday = 1, tuesday, wednesday, thursday, friday, saturday, sunday
}

let chosenDay = DayNumber.friday
print(chosenDay.rawValue)

Recursive Enumerations

Swift allows you to have an enumeration with an instance of itself as the associated value of one or more enumeration cases. This is known as a recursive enumeration. You need to put the indirect keyword before the enumeration case or you can write it before the keyword enum.

enum TypographyExpression {
    case text(String)
    indirect case uppercase(TypographyExpression)
    indirect case lowercase(TypographyExpression)
}

func changeTypography(_ expression: TypographyExpression) -> String {
    switch expression {
    case let .text(value):
        return value
    case let .uppercase(text):
        return changeTypography(text).uppercased()
    case let .lowercase(text):
        return changeTypography(text).lowercased()
    }
}

var myName = "Zakhia"
var expression = TypographyExpression.uppercase(TypographyExpression.text(myName))
myName = changeTypography(expression)
print(myName)
expression = .lowercase(expression)
myName = changeTypography(expression)
print(myName)

Reference

https://docs.swift.org/swift-book/LanguageGuide/Enumerations.html