Master Swift enums [with Examples]

swift Oct 17, 2024
Swift Enums

If you have worked with custom colors in your codebase, you would understand the headache of constantly searching for the right RGB value and the risk of making mistakes by typing or copying the wrong one.

To save yourself from such scenarios, you can use an enum to define all your custom colors or any such related values at one place and use it with ease. Since enums in Swift are type-safe, if you use any undefined or incorrect values, the compiler will throw an error. This makes your code more reliable and easier to maintain.

Table of Contents

  1. What are enums in Swift
  2. How to define an enum in Swift
  3. Swift enum raw values
  4. Implicit raw values in Swift
  5. How to add a computed property to Swift enum
  6. How to iterate over all Swift enum cases
  7. Swift enum with associated values

 

What are enums in Swift?

Enums, short for enumerations, are a user defined data type in Swift that allow you to define a common type for a group of related values. Enums expects that each value defined within it is distinct.

One key characteristic of Swift enums is, they are immutable meaning once an enum case is created, it cannot be changed to another case. Also, enums in Swift are more flexible than any other programming languages as it not only provides a collection of static values but can also have associated values, raw values, and even methods.

 

How to define an enum in Swift

To define an enum, you simply have to use the enum keyword followed by it's name and inside curly braces, you list the distinct values, known as enumeration cases.

Let's create an enum for the different payment methods you want to have in your app.

enum PaymentMethod {
    case creditCard
    case debitCard
    case paypal
    case applePay
}

You can also define an enum by writing all the cases in a single line separated by commas.

enum PaymentMethod {
    case creditCard, debitCard, paypal, applePay
}

There are a few best practices that you must follow while defining enums:

  1. Start the enum name with a capital letter.
  2. Write the cases in camelCase.
  3. Give a singular name to the enum.

Now, in order to use any of the enum cases, you just have to use the enum name followed by a period and choose the desired value from the dropdown list of all the cases available.

var selectedPaymentMethod = PaymentMethod.applePay

Note: Enums in Swift are not associated with integer values just like how you would have seen in other programming languages.

 

Swift enum raw values

Enum cases can also be given default values, called as raw values to associate a constant value such as a string, integer, or any other primitive types. To access the raw value you'll have to use the rawValue property. You also need to make sure that all the raw values of a particular enum are of the same type.

For example, if you're working with HTTP status codes, instead of trying to remember the codes, you can give each enum case a self-explanatory name and map them to their respective codes.

enum HTTPStatusCode: Int {
    case ok = 200
    case notFound = 404
    case internalServerError = 500
}

struct ContentView: View {
    var body: some View {
        Text("HTTP Status Code: \(HTTPStatusCode.ok.rawValue)")
    }
}

In the above code, HTTPStatusCode is defined to be of type Int and all the cases have the Integer type raw values.

Result:

 

Implicit raw values in Swift

If you simply assign Int or String primitive type to the enum and don't explicitly specify the raw values, Swift automatically assigns the raw values based on the type that you have assigned.

If you assign the String type, you will get the text of the enum cases itself as the raw values.

enum PaymentMethod: String {
    case creditCard
    case debitCard
    case paypal
    case applePay
}

struct ContentView: View {
    var body: some View {
        Text(PaymentMethod.paypal.rawValue)
    }
}

Result:

Note that, you also have the flexibility to assign assign raw values only to specific cases.

If you assign the Int type to the enum, you will get the implicit value for each case as one more than the previous case with the first case value being 0, if not specified explicitly.

enum PaymentMethod: Int {
    case creditCard
    case debitCard
    case paypal = 5
    case applePay
}

struct ContentView: View {
    var body: some View {
        VStack {
            Text(PaymentMethod.creditCard.rawValue)
            Text(PaymentMethod.applePay.rawValue)
        }
    }
}

Result:

 

How to add a computed property to Swift enum

When you need each enum case to return a more complex objects or perform an action, you can also use a computed property inside the enum. However, Swift enums can't have stored properties like structs or classes.

Let's say, you want to create an enum to manage custom colors in your app. Now, you can use a computed property to return the corresponding color for each case.

enum CustomColor {
    case lightCoral
    case khaki
    case neon
    case beige
    
    var value: Color {
        switch self {
        case .lightCoral:
            return Color(red: 240 / 255, green: 128 / 255, blue: 128 / 255)
        case .khaki:
            return Color(red: 76.5, green: 69, blue: 56.9)
        case .neon:
            return Color(red: 57/ 255, green: 255 / 255, blue: 20 / 255)
        case .beige:
            return Color(red: 240 / 255, green: 230 / 255, blue: 140 / 255)
        }
    }
}

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .background(CustomColor.neon.value)
    }
}

In the above code, value is a computed property that returns a custom color based on the current enum case.

Result:

One important point to note here is, when using a switch statement with enums, you must handle all the cases. If any case is missing, the compiler will throw an error. That is why using a switch statement is better than if-else with enum as it ensures all the enum cases are covered.

 

How to iterate over all Swift enum cases

Just like how you iterate over all the elements in a collection using a loop, you can also iterate over all the enum cases as well.

To do so, you will have to make your enum conform to the CaseIterable protocol. which gives access to the allCases property to enumerate all cases of an enum.

enum CustomColor: String, CaseIterable {
    case lightCoral
    case khaki
    case neon
    case beige
}

struct ContentView: View {
    var body: some View {
        ForEach(CustomColor.allCases, id: \.self){ colors in
            Text(colors.rawValue)
        }
    }
}

Result:

 

Swift enum with associated values

So far, you have learnt how you can store additional static information against enum cases with raw values. But raw values comes with its own limitations, it requires all the values to be of the same type and you can't use any dynamic value.

Now, what if you want to store information that is of multiple different types for each case. You can achieve this with the support to associated values in enums. With associated values a single enum case can hold different types and amounts of data each time it's used.

Let's say you want to handle server responses with enum where each response might carry different information based on the result.

enum ServerResponse {
    case success(data: String)
    case failure(errorCode: Int, message: String)
}

struct ContentView: View {
    var response: ServerResponse = .failure(errorCode: 404, message: "Not Found")
    
    var body: some View {
        VStack {
            switch response {
            case .success(let data):
                Text("Data received: \(data)")
            case .failure(let errorCode, let message):
                VStack {
                    Text("Error \(errorCode)")
                    Text(message)
                }
            }
        }
    }
}

Result:

 

Where to go next?

Congratulations, today you have learned about the fundamentals of Swift enums, how to define and use them, how to work with raw and associated values and also adding computed properties to it.

We would highly recommend you to learn about more about For loop in Swift and Unit Testing in Swift.

Signup now to get notified about our
FREE iOS Workshops!