Swift Enums
Type-safe way to work with groups of related values
🎯 What are Swift Enums?
Enumerations define a common type for a group of related values. Swift enums are powerful, supporting associated values, methods, and computed properties. They provide type safety and make code more readable and maintainable.
// Basic enum definition
enum Direction {
case north
case south
case east
case west
}
let currentDirection = Direction.north
switch currentDirection {
case .north:
print("Going north!")
case .south:
print("Going south!")
case .east:
print("Going east!")
case .west:
print("Going west!")
}
// Output: Going north!
Key Enum Features
Case Values
Define related constant values
enum Planet {
case mercury, venus, earth, mars
case jupiter, saturn, uranus, neptune
}
Associated Values
Store additional data with enum cases
enum Barcode {
case upc(Int, Int, Int, Int)
case qrCode(String)
}
Raw Values
Assign default values to cases
enum StatusCode: Int {
case ok = 200
case notFound = 404
case serverError = 500
}
Methods & Properties
Add functionality to enums
enum Color {
case red, green, blue
func description() -> String {
return "Color: \(self)"
}
}
🔹 Basic Enum Usage
Here's how to define and use a simple enum:
enum WeatherCondition {
case sunny
case cloudy
case rainy
case snowy
case stormy
}
func getWeatherAdvice(for weather: WeatherCondition) -> String {
switch weather {
case .sunny:
return "Great day for outdoor activities!"
case .cloudy:
return "Perfect for a walk in the park."
case .rainy:
return "Don't forget your umbrella!"
case .snowy:
return "Time to build a snowman!"
case .stormy:
return "Better stay indoors."
}
}
let today = WeatherCondition.sunny
let tomorrow = WeatherCondition.rainy
print(getWeatherAdvice(for: today))
print(getWeatherAdvice(for: tomorrow))
Output:
Great day for outdoor activities!
Don't forget your umbrella!
🔹 Enums with Raw Values
Assign raw values to enum cases for easy conversion:
enum Grade: String {
case excellent = "A"
case good = "B"
case average = "C"
case poor = "D"
case fail = "F"
var description: String {
switch self {
case .excellent:
return "Outstanding work!"
case .good:
return "Good job!"
case .average:
return "Satisfactory"
case .poor:
return "Needs improvement"
case .fail:
return "Must retake"
}
}
}
let studentGrade = Grade.good
print("Grade: \(studentGrade.rawValue)")
print("Feedback: \(studentGrade.description)")
// Create enum from raw value
if let gradeFromString = Grade(rawValue: "A") {
print("Created grade: \(gradeFromString.description)")
}
Output:
Grade: B
Feedback: Good job!
Created grade: Outstanding work!
🔹 Associated Values
Store additional information with enum cases:
enum NetworkResponse {
case success(data: String)
case failure(error: String, code: Int)
case loading
}
func handleResponse(_ response: NetworkResponse) {
switch response {
case .success(let data):
print("Success! Received data: \(data)")
case .failure(let error, let code):
print("Error \(code): \(error)")
case .loading:
print("Loading...")
}
}
let responses: [NetworkResponse] = [
.loading,
.success(data: "User profile loaded"),
.failure(error: "Network timeout", code: 408)
]
for response in responses {
handleResponse(response)
}
Output:
Loading...
Success! Received data: User profile loaded
Error 408: Network timeout
🔹 Enum Methods and Computed Properties
Add functionality directly to your enums:
enum Size: String, CaseIterable {
case small = "S"
case medium = "M"
case large = "L"
case extraLarge = "XL"
var price: Double {
switch self {
case .small:
return 10.0
case .medium:
return 12.0
case .large:
return 15.0
case .extraLarge:
return 18.0
}
}
func isLargerThan(_ other: Size) -> Bool {
return self.price > other.price
}
static func allSizes() -> String {
return Size.allCases.map { $0.rawValue }.joined(separator: ", ")
}
}
let mySize = Size.large
let otherSize = Size.medium
print("Size \(mySize.rawValue) costs $\(mySize.price)")
print("Is \(mySize.rawValue) larger than \(otherSize.rawValue)? \(mySize.isLargerThan(otherSize))")
print("Available sizes: \(Size.allSizes())")
Output:
Size L costs $15.0
Is L larger than M? true
Available sizes: S, M, L, XL
🔹 Best Practices
Follow these guidelines when working with enums:
✅ Good Practices:
- Use descriptive names: Make enum cases self-explanatory
- Group related values: Only put related constants in the same enum
- Leverage switch statements: Handle all cases for type safety
- Add methods when useful: Enums can have behavior, not just data
- Use CaseIterable: When you need to iterate over all cases
💡 When to Use Enums:
- Representing a fixed set of options (directions, states, types)
- Modeling different types of data (success/failure, different shapes)
- Creating type-safe constants instead of strings or integers
- Implementing state machines or finite state systems