- August 28, 2025
- Mins Read
An enumeration (or enum) in Swift defines a common type for a group of related values, and enables you to work with those values in a type-safe way.
// Basic enum with no raw values
enum CompassPoint {
case north
case south
case east
case west
}
// Shorthand: multiple cases on one line
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
enum
keyword introduces the type.case
defines one of the possible values.You can associate each case with a raw value (of type String
, Int
, etc.), which lets you convert between the enum and its underlying value.
enum Weekday: Int {
case monday = 1, tuesday, wednesday, thursday, friday, saturday, sunday
}
enum Direction: String {
case north = "N", south = "S", east = "E", west = "W"
}
// Implicit raw-value incrementing for integers, and implicit string raw-values matching case names:
enum Fruit: String {
case apple, banana, cherry
}
// Fruit.banana.rawValue == "banana"
init?(rawValue:)
.A switch
on an enum is exhaustive, so you must cover all cases (or include a default
).
let direction: CompassPoint = .west
switch direction {
case .north:
print("Heading north")
case .south:
print("Heading south")
case .east:
print("Heading east")
case .west:
print("Heading west")
}
Key points:
switch
already knows the type (.west
instead of CompassPoint.west
).switch direction {
case .north, .south:
print("Moving vertically")
case .east, .west:
print("Moving horizontally")
}
To loop over all cases of an enum, your type must conform to the CaseIterable
protocol:
enum Beverage: CaseIterable {
case coffee, tea, juice, water
}
for drink in Beverage.allCases {
print(drink)
}
// Prints: coffee, tea, juice, water
: CaseIterable
to the enum definition.allCases
array.let randomBeverage = Beverage.allCases.randomElement()!
Associated values let each case carry its own custom data—think of them like lightweight unions or tagged payloads.
enum Barcode {
case upc(Int, Int, Int, Int) // tuple of four Ints
case qrCode(String) // one String
}
var productBarcode = Barcode.upc(8, 85909, 51226, 3)
productBarcode = .qrCode("ABCDEFGHIJKLMNOP")
Use a switch
to bind and extract:
switch productBarcode {
case .upc(let numberSystem, let manufacturer, let product, let check):
print("UPC: \(numberSystem), \(manufacturer), \(product), \(check)")
case .qrCode(let code):
print("QR code: \(code)")
}
let
:
case let .upc(numberSystem, manufacturer, product, check):
_
:
case let .upc(_, manufacturer, product, _):
print("Manufacturer: \(manufacturer), product: \(product)")
You can name the elements to improve readability:
enum Measurement {
case weight(kg: Double)
case age(years: Int)
}
let m = Measurement.weight(kg: 68.5)
switch m {
case .weight(kg: let w):
print("Weight: \(w) kg")
case .age(years: let y):
print("Age: \(y) years")
}
While you can’t mix raw values and associated values on the same enum directly, you can simulate it by using init?(rawValue:)
or custom initializers and computed properties.
Imagine you’re parsing messages from a server, where each message can be text, an image with a URL, or a reaction:
enum ChatMessage: CaseIterable {
case text(String)
case image(url: URL, thumbnailURL: URL)
case reaction(emoji: String, toMessageID: Int)
}
// Iterating all possible message "types" (for analytics, UI tabs, etc.):
for type in ChatMessage.allCases {
print("Supported type: \(type)")
}
// Handling an incoming message:
func handle(_ message: ChatMessage) {
switch message {
case .text(let content):
showText(content)
case let .image(url, thumbnail):
showImage(from: url, placeholder: thumbnail)
case .reaction(let emoji, let messageID):
addReaction(emoji, to: messageID)
}
}
This pattern keeps your code:
switch
statements needing updates.Feature | Syntax / Notes |
---|---|
Declaration | enum Name { case a, b, c } |
Raw values | enum E: Int { case one = 1, two, three } / enum S: String { case foo = "foo" } |
Associated values | case foo(Int, String) / case bar(name: String, age: Int) |
Switch matching | switch value { case .foo(let x, let y): … case .bar: … } |
Combining cases | case .a, .b: … |
CaseIterable | enum E: CaseIterable { … } → E.allCases |
Failable raw-value init | let e = E(rawValue: 2) returns E? |
Implicit init for String raw | enum X: String { case a, b } → X.a.rawValue == "a" |
Ignoring values | case .foo(_, let important, _) |
Binding multiple | case let .foo(x, y, z): |
This package provides you with an easy way to show tooltips over any SwiftUI view, since Apple does not provide ...
SimpleToast is a simple, lightweight, flexible and easy to use library to show toasts / popup notifications inside iOS or ...
Create Toast Views with Minimal Effort in SwiftUI Using SSToastMessage. SSToastMessage enables you to effortlessly add toast notifications, alerts, and ...