# Enums with Associated Values — Swift

Source: https://www.skillbyai.com/en/swift/t-enums

> Model states and choices with enums, raw values, associated values and methods.

## Enums that carry data

Swift **enums** define a type with a fixed set of **cases**, and they are far more powerful than integer constants. Cases can have **raw values** (`enum Size: String { case small = "S" }`), giving free conversion with `Size(rawValue:)`. Cases can carry **associated values** of different types: `case card(last4: String)`, `case upi(vpa: String)`, `case cash`. That lets you model **states that hold different data**, such as `.loading`, `.loaded([Product])` and `.failed(Error)`, making invalid combinations impossible to represent. Enums can have methods, computed properties and initialisers, conform to protocols, and be made **`CaseIterable`** to list all cases. Switching over an enum must handle every case, so adding a new case makes the compiler show every place that needs updating. Use `indirect` for recursive enums such as expression trees. Swift's `Optional` and `Result` are themselves enums.

## Modelling payment methods and screen state

Associated values keep data with the case it belongs to.

```swift
enum PaymentMethod {
    case upi(vpa: String)
    case card(last4: String, network: String)
    case netBanking(bankCode: String)
    case cashOnDelivery

    var label: String {
        switch self {
        case .upi(let vpa):                 "UPI \(vpa)"
        case .card(let last4, let network):  "\(network) •••• \(last4)"
        case .netBanking(let bank):          "Net banking (\(bank))"
        case .cashOnDelivery:                "Cash on delivery"
        }
    }
}

enum LoadState<Value> {
    case idle
    case loading
    case loaded(Value)
    case failed(String)
}

enum Size: String, CaseIterable { case small = "S", medium = "M", large = "L" }

let method = PaymentMethod.card(last4: "4242", network: "RuPay")
print(method.label)
print(Size.allCases.map(\.rawValue))      // ["S", "M", "L"]
let parsed = Size(rawValue: "M")           // Optional(.medium)
```

## A form with sections per choice

An enum with associated values is a form where ticking "card" reveals only the card fields and ticking "UPI" reveals only the UPI field. You can never end up with a half-filled mixture of both.

**Quiz:** What advantage do associated values give enums?

- [ ] They make enums faster
- [ ] They allow inheritance
- [ ] They remove the need for switch
- [x] Each case can carry its own relevant data, making invalid states unrepresentable

*Answer:* Each case can carry its own relevant data, making invalid states unrepresentable. Associated values keep exactly the data each case needs.
