Swifty Waves

TODO: Explore the seven ways to deal with Optionals

Swift Optionals

Swift has introduced (at least for the iOS development ecosystem) the concept of Optionals.

An optional is a struct that can have two values, a nil value or "a" value.

From Apple's documentation:

You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.

Along the code we want/need to access those optionals. We can access through several ways:

If Statements

We can test, using the if statement, if an optinal is nil or not.

if convertedNumber != nil {
    print("convertedNumber contains some integer value.")
}

After testing for nil, if we want to access the value (already knowing that the variable is not nil), we can use the Forced Unwrapping.

Forced Unwrapping

Basically we force the unwrapping because we "are sure" that the optional contains a value:

if convertedNumber != nil {
    print("convertedNumber has an integer value of \(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."

This is, however, a bit verbose. It can also be dangerous if we avoid the if check based on the logic and in the "feeling" that such optional has a value.

Optional Binding

Is a more elegant and secure way of doing the unwrapp.

if let actualNumber = Int(possibleNumber) {
    print("\"\(possibleNumber)\" has an integer value of \(actualNumber)")
} else {
    print("\"\(possibleNumber)\" could not be converted to an integer")
}
// Prints ""123" has an integer value of 123"

The main problem is that can be a bit verbose and cause a chain of optional bindings.

Implicitly Unwrapped Optionals

In some cases it’s clear from an optional will always have a value after some operation(ex: value first set). Thus, it’s useful to remove the need to always check and unwrap the optional’s value. This is because we can assumed that the optional has a value all of the time.

In that case we can use implicitly unwrapped optionals.

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

This requires some caution because:

If an implicitly unwrapped optional is nil and you try to access its wrapped value, you’ll trigger a runtime error. The result is exactly the same as if you place an exclamation mark after a normal optional that doesn’t contain a value.

Tagged with: