Course

Swift Enum: Syntax, Usage, and Examples

Enums in Swift define a group of related values under a single type. They help you write safer, more readable code by eliminating magic numbers and strings. Unlike enums in some other languages, Swift enums can store associated values and methods, making them highly flexible. They also support raw values and can conform to protocols, which enhances their usability across different programming scenarios.

How to Use Enums in Swift

Enums use the enum keyword followed by a list of cases. Each case represents a possible value.

swift
enum Direction { case north case south case east case west }

Assigning Enum Values

You can assign an enum value to a variable or constant using dot notation.

swift
let currentDirection: Direction = .west

If the type is already known, you can omit the enum name for brevity.

swift
var nextMove = Direction.east

Switching on Enum Cases

Using a switch statement with enums makes handling different cases easy and eliminates the need for lengthy if statements.

swift
switch currentDirection { case .north: print("Heading north") case .south: print("Heading south") case .east: print("Heading east") case .west: print("Heading west") }

Since Swift requires switch statements to be exhaustive, you must cover all cases or use a default case.

When to Use Enums in Swift

Enums help eliminate hardcoded values and make your code more maintainable. They are useful in several scenarios, including defining states, handling API responses, and managing configurations.

Grouping Related Values

Enums allow you to replace strings or integers when defining a set of possible values. Instead of using "monday", "tuesday", and so on, you can use an enum for better safety.

swift
enum Day { case monday, tuesday, wednesday, thursday, friday, saturday, sunday }

Handling API Responses

Enums make handling API responses structured by replacing status codes or response strings with well-defined cases.

swift
enum StatusCode { case success case error case loading }

This approach reduces the risk of typos and makes response handling more predictable.

Defining State Machines

Enums work well for managing state in an application. For example, you can use an enum to track a user’s authentication state.

swift
enum AuthState { case loggedIn, loggedOut, inProgress }

Examples of Enums in Swift

Using Enums with Raw Values

You can assign raw values to enums, which is useful when storing integer or string representations of a case.

swift
enum HTTPStatus: Int { case ok = 200 case notFound = 404 case serverError = 500 } let responseCode = HTTPStatus.ok.rawValue print(responseCode) // Output: 200

Enums with Associated Values

Enums can store associated values, allowing you to attach additional data to each case.

swift
enum Payment { case cash(amount: Double) case card(number: String, expiry: String) } let transaction = Payment.card(number: "1234-5678-9012-3456", expiry: "12/24") switch transaction { case .cash(let amount): print("Paid in cash: \(amount)") case .card(let number, let expiry): print("Paid with card ending in \(number.suffix(4)), expires \(expiry)") }

This feature allows you to store different data types within a single enum.

Enum Methods

You can define methods inside an enum to add behavior directly to its cases.

swift
enum TrafficLight { case red, yellow, green func description() -> String { switch self { case .red: return "Stop" case .yellow: return "Slow down" case .green: return "Go" } } } let light = TrafficLight.red print(light.description()) // Output: Stop

Adding methods to enums helps keep related logic together, improving code organization.

Comparing Enums

You can compare enum values using the equality operator.

swift
if light == .red { print("You must stop.") }

This ensures type safety since only valid cases can be compared.

Learn More About Enums in Swift

Swift enums offer additional features like default values, protocol conformance, and computed properties.

Enum with Default Values

If an enum has raw values, you can initialize an instance using init(rawValue:). This allows you to convert external data into an enum safely.

swift
enum SeatClass: String { case economy = "Economy" case business = "Business" case first = "First Class" } let chosenSeat = SeatClass(rawValue: "Business")

If the provided raw value doesn’t match any case, the initializer returns nil, which makes it useful for handling unknown data.

Enum with Protocols

Enums can conform to protocols, enabling shared behavior across different types.

swift
protocol Printable { func printValue() } enum Vehicle: Printable { case car, bike, bus func printValue() { print(self) } } let myVehicle = Vehicle.car myVehicle.printValue() // Output: car

This technique allows enums to work seamlessly with other types in your code.

Using Enums as Function Parameters

Passing enums as function parameters ensures type safety and improves code clarity.

swift
func setTheme(_ theme: Theme) { switch theme { case .dark: print("Dark mode activated") case .light: print("Light mode activated") } } enum Theme { case dark, light } setTheme(.dark)

This method prevents invalid values from being passed to functions, reducing bugs.

Enums Inside Classes

Enums can be nested within classes or structs, making them more modular.

swift
class Car { enum Transmission { case manual, automatic } let transmission: Transmission init(transmission: Transmission) { self.transmission = transmission } } let myCar = Car(transmission: .automatic)

By nesting enums, you can keep related data encapsulated within its relevant context.

Best Practices for Using Enums

  • Use camelCase for enum cases (case active instead of case ACTIVE).
  • Prefer switch statements over ifelse for handling enum values.
  • Store associated values instead of separate variables when relevant.
  • Use raw values only when necessary (e.g., mapping to API values).
  • Consider protocol conformance if you need shared behavior across enums.