Enum in Swift is a type that unites a group of related values under a single name. Unlike C and Objective-C, where enum is just a set of integer constants, Swift offers first-class enumerations with associated values, raw values, methods, and protocol support. According to Apple, 2026, enum is one of the key tools for type-safe state modeling in iOS development.
Key Takeaways
Enum (enumeration) is a custom data type that unites a finite set of mutually exclusive variants. In Swift, enum is not just numeric constants, but a full-fledged type with its own logic.
Each enumeration variant is called a case. Unlike Objective-C, where enum boils down to an integer type, Swift allows each case to store its own data and have methods.
According to Apple, enum in Swift supports generics, initializers, computed properties, and protocol conformance — making it applicable for modeling states, errors, options, and finite state machines.
Use enum wherever you need to represent a finite set of mutually exclusive variants: screen states, error types, directions, filtering options.
Enum is declared with the keyword enum followed by a name and a body in curly braces.
enum CompassDirection {
case north
case south
case east
case west
}
Cases can be declared on a single line separated by a comma:
enum Planet {
case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}
To access a case, use dot syntax after the known type:
let direction = CompassDirection.north
// Type is known — shorthand syntax is available:
var currentPlanet = .earth
Once a variable is assigned a known enum type, Swift automatically infers the type, allowing you to omit the enum name when accessing cases.
Raw Values are values of a single type assigned to each enum case. Unlike associated values, raw values are of the same type for all cases and are defined at declaration time.
enum HTTPStatusCode: Int {
case ok = 200
case notFound = 404
case internalServerError = 500
}
let code = HTTPStatusCode.notFound
print(code.rawValue) // 404
For integer raw values, Swift automatically increments values if only the first one is explicitly set:
enum Status: Int {
case pending = 1
case active // 2
case completed // 3
}
Raw values can be of types Int, String, Character, or any type conforming to the RawRepresentable protocol. Swift automatically generates the init? initializer to create an enum from a raw value — convenient for parsing data from APIs.
Associated Values allow binding different data types to each enum case individually. Unlike raw values, associated values can differ in type and quantity.
enum NetworkError {
case timeout(seconds: Int)
case httpError(code: Int, message: String)
case noConnection
case unknown(error: Error)
}
When processing with switch, associated values are extracted through binding to variables or constants:
let error = NetworkError.httpError(code: 403, message: "Forbidden")
switch error {
case .timeout(let seconds):
print("Timeout after \(seconds)s")
case .httpError(let code, let message):
print("HTTP \(code): \(message)")
case .noConnection:
print("No connection")
case .unknown(let err):
print("Unknown: \(err.localizedDescription)")
}
According to Apple documentation, associated values make enum an expressive tool for modeling complex states without creating separate wrapper types. Use them for Result-like scenarios and modeling errors with context.
Recursive enum — an enumeration whose cases refer to the enum type itself. Such cases are marked with the keyword indirect.
indirect enum LinkedList<T> {
case empty
case node(value: T, next: LinkedList<T>)
}
Using indirect before enum marks all cases as recursive. Alternatively, you can mark only a specific case with indirect:
enum ArithmeticExpression {
case number(Int)
indirect case addition(ArithmeticExpression, ArithmeticExpression)
indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}
Swift uses indirect to store recursive cases as references (reference semantics) instead of values — this prevents infinite enum size on the stack. Recursive enums are widely used in building trees, linked lists, and ASTs.
Enum can conform to protocols just like structures and classes. This is a key feature of protocol-oriented programming in Swift.
protocol Describable {
var description: String { get }
}
enum PaymentMethod: Describable {
case creditCard(last4: String)
case applePay
case bankTransfer
var description: String {
switch self {
case .creditCard(let last4):
return "Card ending in \(last4)"
case .applePay:
return "Apple Pay"
case .bankTransfer:
return "Bank Transfer"
}
}
}
Enum can also conform to Cocoa protocols — for example, CaseIterable for automatic generation of a collection of all cases, or Codable for serialization. This makes enum a versatile building block in Swift applications.
Frequently Asked Questions
Enum is a type with a finite set of mutually exclusive variants, while struct is a type with an arbitrary set of properties. Enum cannot have stored properties but supports computed properties and methods.
No, an enum cannot have both raw values and associated values simultaneously. Raw values are values of the same type for all cases, while associated values are individual data for each case. These mechanisms are mutually exclusive.
Add conformance to the CaseIterable protocol. Swift will automatically generate the allCases property, returning a collection of all cases in declaration order. This is convenient for iterating over all variants.
Switch is the safest approach because the compiler checks for exhaustive coverage. You can use if case to check a single case or == for enums without associated values.
Yes, enum supports generics: enum Result<T, E> { case success(T); case failure(E) }. This allows creating type-safe generic constructs for handling success and error.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also