Enumerations (or enums for short) in Swift define a common type for a group of related values. According to the Swift documentation, enums enable you to work with those values in a type-safe way within your code. Enums come in particularly handy when you have a lot of different options you want to encode.
Using enum in Swift is similar to writing code that returns a boolean — e.g., true or false — when a condition is met. In the case of enums, however, you can have more than two possible values.
Think of an enum like a thermostat. There is a range of values that could possibly match the outcome — e.g., low, medium, high, extreme. Depending on the case that is matched, we’ll want to run some specified code.
An enum is a special type of variable that is specifically used with switch and conditionals. Swift enumeration cases don’t have unique default integer values (like an array), unlike languages such as TypeScript and Objective C where the first element has a value of 0, the second a value of 1, and so on.
In this tutorial, we’ll cover all the basics of Swift enums, including:
CaseIterable in enumeration casesThe Replay is a weekly newsletter for dev and engineering leaders.
Delivered once a week, it's your curated guide to the most important conversations around frontend dev, emerging AI tools, and the state of modern software.
To define an enum in Swift, use the keyword enum followed by the name of the enum. The name of an enum in Swift should follow the PascalCase naming convention in which the first letter of each word in a compound word is capitalized.
// starts with the keyword 'enum'and follows the PascalCase naming convention
enum EnumerationNmae {
// our enum values (case) goes in here
}
Here is a closer look at how to declare values in an enum:
enum Direction {
case up
case down
case left
case right
}
The values declared in an enum — up, down, left and right — are referred to as enumeration case. We use the case keyword to introduce a new enumeration case.
Enums are particularly useful inside switch statements, as opposed to an if-else statement. That’s because in a switch statement Swift knows all the values the enum holds, so it will ensure you cover all the cases in your enum or add a default case.
CaseIterable in enumeration casesCaseIterable is a type that provides a collection of all the values of an enumeration. It’s used to iterate over all the cases in an enum.
To do this, add CaseIterable after the name of the enum. With that in place, Swift will give us access to a collection of all the cases through a property on the enumeration type called allCases.
enum CarBrand: String, CaseIterable {
case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
case Toyota = "Known for high-quality, high-value cars"
case Volkswagen = "This is the people's car"
case Ford = "Known for crisp handling, absorbent ride, and solid feel"
case Honda = "Known for their well-built, reliable cars"
}
To access the collection of all the cases in our CarBrand enum, we can do this:
print(CarBrand.allCases.count) // expected output: 5
In the example above, we wrote CarBrand.allCases to access a collection that contains all of the cases of the CarBrand enumeration. The count method gives the number of elements in our collection.
We can go further by using a for loop over all the cases in our enum.
Let’s print put the raw value in our enumeration cases using the allCases method:
// create an enum with a CaseIterable type
enum CarBrand: String, CaseIterable {
case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
case Toyota = "Known for high-quality, high-value cars"
case Volkswagen = "This is the people's car"
case Ford = "Known for crisp handling, absorbent ride, and solid feel"
case Honda = "Known for their well-built, reliable cars"
}
// we are looping through our enum and accessing all its raw values
for brand in CarBrand.allCases {
print(brand.rawValue)
}
// expected output:
// Known for luxury and iconic design. Definitely my fav!
// Known for high-quality, high-value cars
// This is the people's car
// Known for crisp handling, absorbent ride, and solid feel
// Known for their well-built, reliable cars
In our enum, we can declare a raw value type. This essentially means attaching a value to the enum case.
To better understand raw values in enums, let’s create an enum of type string (it can be any type) to hold different brands of cars along with attributes for which each brand is known (these will be the raw values):
// Enum with raw values
enum CarBrand: String {
case Mercedes = "Known for luxury and iconic design. Definitely my fav!"
case Toyota = "Known for high-quality, high-value cars"
case Volkswagen = "This is the people's car"
case Ford = "Known for crisp handling, absorbent ride, and solid feel"
case Honda = "Known for their well-built, reliable cars"
}
To set a value to your enum, you need to assign a data type to it. In our case above, we are using a type of String.
Each raw value for our enum case must be a unique string, character, or value of any integer or floating-point type. This means the value for the two case statements cannot be the same. See the code below:
enum CarBrand: String {
case Toyota = "High value cars."
case Volkswagen = "High value cars."
}
The code above throws an error of “Raw value for enum case is not unique” because both case values are exactly the same.
Now that we’ve created our enum with each enumeration case having a raw value, let’s create a function that will return the rawValue of the various car brands. The raw values here represent the attributes each brand is known for:
func carKnownFor(brand: CarBrand) -> String {
return brand.rawValue
}
carKnownFor(brand: .Ford)
carKnownFor(brand: .Mercedes)
// expected output:
// "Known for luxury and iconic design. Definitely my fav!"
// "Known for crisp handling, absorbent ride, and solid feel"
One of the best features of enumerations in Swift is that you can have values that you define attach to enums in each case. This enables you to attach additional information to your enums so they can represent more meaningful data.
For example, let’s say we have an enum that defines the prices of Mercedes cars. Based on the price, we want to determine whether a user can afford the model of car or not. We can associate a price with the brand of car in our enum as we have in the example below:
// enum with associated values
enum MercedesModelPrice {
case MayBach(price: Int)
case AMG_GT(price: Int)
case Metris(price: Int)
case SprinterWagon(price: Int)
case GClass
}
// enum without associated values
enum MercedesModelPrice {
case MayBach
case AMG_GT
case Metris
case SprinterWagon
case GClass
}
Now, let’s create a function to check whether a user can afford a Mercedes:
func getMercedesPrice(for mercedesModel: MercedesModelPrice) {
switch mercedesModel {
case .MayBach(price: let price) where price >= 100_000:
print("You just bought yourself a new car")
case .Metris(price: let price) where price >= 86_000:
print("You just bought yourself a new car")
case .AMG_GT(price: let price) where price >= 74_000:
print("You just bought yourself a new car")
case .SprinterWagon(price: let price) where price >= 45_000:
print("You just bought yourself a new car")
case .GClass, .SprinterWagon, .Metris, .AMG_GT, .MayBach:
print("Insufficient funds. You cant' afford this car at the moment")
}
}
// Calling our function
getMercedesPrice(for: .SprinterWagon(price: 200_000))
// expected output: You just bought yourself a new car
Notice how we’re using the where keyword to filter the case for a specific price.
It’s worth noting that the order of the case statement matters. Putting the last case statement (case .GClass, .SprinterWagon, .Metris, .AMG_GT, .MayBach:) first means we’ll always get the result attached to this case as a match.
Apart from defining enumeration cases in our enum, we can also define methods in our enum, like this:
enum Weekday {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
case Saturday
case Sunday
func dayType() -> String {
switch self {
case .Sunday, .Saturday:
return "Weekend"
default:
return "Weekday"
}
}
}
Weekday.Monday.dayType()
// this will return "Weekday"
Weekday.Sunday.dayType()
// this will return "Weekend"
In the code snippet above, we’re using the switch statement within the dayType method to return Weekend or Weekday as the output depending on the day of the week.
You can also use computed properties in enums in place of functions.
Let’s replace the dayType function we have in our code above with a computed property:
enum Weekday {
case Monday
case Tuesday
case Wednesday
case Thursday
case Friday
case Saturday
case Sunday
var dayType: String {
self == .Saturday || self == .Sunday ? "Weekend" : "Weekday"
}
}
Weekday.Monday.dayType
// this will return "Weekday"
Weekday.Sunday.dayType
// this will return "Weekend"
>
Swift enums can be a powerful way to simplify your code. In this tutorial, we covered the syntax of enums and how to define them, how to create enumeration cases, and how to use them in switch statements. We also defined CaseIterable as a type that provides a collection of all the values of the enumeration. We covered enum values (both raw and associated values) and how to use them in our codebase. Finally, we demonstrated how to use computed properties in Swift enums in place of functions.
Install LogRocket via npm or script tag. LogRocket.init() must be called client-side, not
server-side
$ npm i --save logrocket
// Code:
import LogRocket from 'logrocket';
LogRocket.init('app/id');
// Add to your HTML:
<script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script>
<script>window.LogRocket && window.LogRocket.init('app/id');</script>

line-clamp to trim lines of textMaster the CSS line-clamp property. Learn how to truncate text lines, ensure cross-browser compatibility, and avoid hidden UX pitfalls when designing modern web layouts.

Discover seven custom React Hooks that will simplify your web development process and make you a faster, better, more efficient developer.

Promise.all still relevant in 2025?In 2025, async JavaScript looks very different. With tools like Promise.any, Promise.allSettled, and Array.fromAsync, many developers wonder if Promise.all is still worth it. The short answer is yes — but only if you know when and why to use it.

Discover what’s new in The Replay, LogRocket’s newsletter for dev and engineering leaders, in the October 29th issue.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up now