DEV Community

Jaume Viñas Navas
Jaume Viñas Navas

Posted on

3

Swift Enumerations (Part 2)

In this new chapter we will cover more advanced features about Swift enumerations, remember to read the first chapter if you missed it or you want to refresh the basic concepts of Swift enums.

Associated Values

Enumeration cases have their own value and type, and sometimes it is useful to store additional data of other types alongside an enum case. Associated values are a fantastic way to achieve that by attaching custom information along with the case value, allowing this information to be different each time you use that enum case in your code.

Here’s an example of an enumeration that defines a set of actions that users can execute in order to modify a layer. A layer can be resized, rotated and filled with a color. The enum case resize has two associated values that define the new width and height values of the layer, the enum case rotate has one associated value which indicates the rotation degrees, and the enum case fill has one associated value that indicates the color of the layer.

enum LayerActions {
case scale(width: Double, height: Double)
case rotate(degrees: Double)
case fill(hex: String)
}
let scale = LayerActions.scale(width: 120, height: 60)
let fill = LayerActions.fill(hex: "#FFFFFF")
view raw enums_av.swift hosted with ❤ by GitHub

The associated values can be accessed using a switch statement, and they can be extracted as constants (with the let prefix) or as variables (with the var prefix).

let fill = LayerActions.fill(color: "#FFFFFF")
switch fill {
case .scale(let width, let height):
print("Layer size: \(width)x\(height)")
case .rotate(let degrees):
print("Layer rotation: \(degrees)")
case .fill(let color):
print("Layer color: \(color)")
}

Methods

Enumerations in Swift are first-class types in their own right. They adopt many features traditionally supported only by classes, for example, instance methods to provide functionality related to the values the enumeration represents.

Methods on enumerations exist for every enum case. If you want to provide specific code for every enum case, you need a switch statement to determine each case.

enum Polygon {
case triangle, quadrilateral, pentagon, hexagon
func description() -> String {
switch self {
case .triangle:
return "A triangle is a polygon with three egdes"
case .quadrilateral:
return "A quadrilateral is a polygon with four egdes"
case .pentagon:
return "A pentagon is a polygon with five egdes"
case .hexagon:
return "An hexagon is a polygon with six egdes"
}
}
}

Mutating Methods

By default, the properties of an enumeration cannot be modified from within its instance methods. However, if you need to modify your enumeration you can use mutating methods. Mutating methods for enumerations can set the implicit self parameter to be a different case from the same enumeration.

Here’s an example that defines an enumeration for a temperature alarm with two states, enabled and disabled. The enumeration changes its state when the temperature reaches an specific threshold.

enum Alarm {
case enabled, disabled
mutating func newReading(temperature: Double) {
if (temperature > 300) {
self = .enabled
} else {
self = .disabled
}
}
func description() -> String {
switch self {
case .enabled:
return "Alarm is enabled"
case .disabled:
return "Alarm is disabled"
}
}
}
var ovenAlarm = Alarm.disabled
ovenAlarm.newReading(temperature: 340)
ovenAlarm.description() // "Alarm is enabled"

Properties

Event though enumerations can’t have stored properties, they can have computed properties to provide additional information about the enumeration’s current value.

The example below modifies the Polygon enumeration in order to add a new property edges . This new property returns the number of edges of the enum case. The method description() has also been updated in order to use the new property.

enum Polygon {
case triangle, quadrilateral, pentagon, hexagon
var edges: Int {
switch self {
case .triangle:
return 3
case .quadrilateral:
return 4
case .pentagon:
return 5
case .hexagon:
return 6
}
}
func description() -> String {
switch self {
case .triangle:
return "A triangle is a polygon with \(self.edges) egdes"
case .quadrilateral:
return "A quadrilateral is a polygon with \(self.edges) egdes"
case .pentagon:
return "A pentagon is a polygon with \(self.edges) egdes"
case .hexagon:
return "An hexagon is a polygon with \(self.edges) egdes"
}
}
}

If you find this post helpful, please recommend it for others to read. In the next chapter we will cover more advanced enumeration usages such as protocols, extensions, generics and custom initializers.

Heroku

Simplify your DevOps and maximize your time.

Since 2007, Heroku has been the go-to platform for developers as it monitors uptime, performance, and infrastructure concerns, allowing you to focus on writing code.

Learn More

Top comments (0)

Sentry mobile image

Mobile Vitals: A first step to Faster Apps

Slow startup times, UI hangs, and frozen frames frustrate users—but they’re also fixable. Mobile Vitals help you measure and understand these performance issues so you can optimize your app’s speed and responsiveness. Learn how to use them to reduce friction and improve user experience.

Read the guide →

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay