Best Practices for Using Optionals in Swift
Frustrated by seeing “Fatal error: Unexpectedly found nil while unwrapping an Optional value”?
We use optionals very frequently in our Swift projects. When they’re used improperly, we can encounter this error in Xcode.
Fatal error: Unexpectedly found nil while unwrapping an Optional value
Whenever it happens during an app’s runtime, the app will crash reliably, resulting in an immediate rejection of the app during the App Store’s review process.
Thus, it’s very critical to prevent this from happening — ideally in the app development phase.
In this article, I’ll review the best practices for using optionals in Swift.
What Are Optionals?
Optionals are data types that either represent a value or no value at all.
For example, in the following code, we declare an optional string called
name. As you can see, the
name variable can have the assigned value of
John or have no value after setting it to
After having a first feel with the optional string, let’s see how Apple defines the Optional.
“A type that represents either a wrapped value or
nil, the absence of a value.”
The declaration of this data type is the below.
@frozen enum Optional<Wrapped>
As you can tell, it’s a generic enumeration, but what cases does it have? The Optional has two cases.
none case is the absence of any value, often expressed as
nil, while the
some(Wrapped) case is the wrapped value of the defined data type, such as
Dictionary, and custom
Thus, it has been conceptualized by some people that optionals can be viewed as containers of some data types.
There are multiple ways to declare an optional. One thing to note is that if we declare an optional, we have to be specific about the wrapped data type, as Optional is a generic enumeration, and thus the use of this generic data type has to involve a concrete data type, such as
For example, the following declaration has the error:
Reference to generic type ‘Optional’ requires arguments in <…>.
var optionalValue: Optional?
Use trailing question mark
The most common way to declare an optional is to use a trailing question mark (
?) following the specific data type.
The following code creates optionals of various data types, including
One thing to note is that when we declare an optional of a generic data type, such as
Dictionary, we have to be specific about the exact data type of these generic data types.
For example, the following declarations have the errors of using the generic data types without data specificity.
var names: Array?
var information: Dictionary?
To solve this problem, we can just specify the element’s data type for the
Dictionary as we did in the above code snippet.
One interesting feature in Swift is that you can append a question mark to an optional data type to make it an optional optional data type, which can repeat multiple times if you want. It’s like something below.
var optional0: String? // an optional String
var optional1: String?? // an optional String?
var optional2: String??? // an optional String??
...and so on
Use the Optional<Wrapped>
Another less-used way to declare optionals is to use the form of
Wrapped is the specific data type. The following code snippet shows you the declarations of the same variables shown above.
It should be noted that both ways of declarations have exactly the same effects, but the first one using a question mark is preferred because of its better readability.
Use trailing exclamation mark
Another relatively common way to declare an optional is to add a trailing exclamation mark (
!) to a data type (e.g.,
Int), which are termed Implicitly Unwrapped Optionals.
No worries if you’re unfamiliar with this term because we’ll expand on this concept later in this article. Some relevant code is given below.
As you can expect, the
lastName variable is the
Optional<String> data type. However, if you append the trailing exclamation mark to an optional that is declared using the
Optional<Wrapped> approach, things behave differently.
As you can see for the
firstName variable, its type is an optional
String?, but not an optional
This result shares the same concept of creating optional optionals appending multiple question marks to a data type, like
String as we covered in the first part (Use Question Mark section).
When we declare optionals, we can assign values to these variables if we want. If we don’t assign any values, all optionals have the default “value” —
nil, the absence of a value.
The following code shows you how various assignments can be done.
For example, we can use the Optional’s
none case to assign to an optional, which makes the variable have a
nil value. Similarly, we can use the
some<Wrapped> case to assign a value of the wrapped data type to an optional.
Alternatively, we can assign an optional value to an optional variable. In the example, when we use the
middleName string to access the key’s value in a
Dictionary<String, String>, the return data type is
String? type, as it’s likely that the key doesn’t exist in the
Please note that even if we know that the key (e.g.,
firstName) exists, the return data type is still
String? because at runtime, a
Dictionary’s key list can always be subject to change.
To use optionals in most contexts, we need to unwrap optionals to access their wrapped values if not
nil. There are different scenarios of how we unwrap optionals as summarized below.
When we’re certain that the optional contains a value, we can use the exclamation mark (
!) following the variable name to unconditionally unwrap the value.
Note that when we declare an optional, we use the exclamation mark following a data type, unlike the unwrapping which follows a variable.
In the Declarations section, we briefly mentioned the concept of Implicitly Unwrapped Optionals. Here, we explain what it is.
Basically, we use an exclamation mark to declare an optional variable of a certain type, let’s say
String, and the variable name is called
Every time we use this variable, we can omit the forced unwrapping operator (i.e., post-fix
!) to unwrap the optional. In reality, the compiler will unconditionally unwrap this optional for us, and this is why it’s called implicit unwrapping.
Therefore, even though we don’t explicitly use the post-fix
! following the variable, it’s still our responsibility to make sure that the optional is not
nil, as forced unwrapping is still happening behind the scene.
When the optional happens to be
nil, unwrapping it will lead to the fatal error as shown at the beginning of this article. See some relevant examples below.
Since some behaviors can be unpredictable if we use forced unwrapping, we can use optional binding which conditionally unwraps an optional.
To do that, we can use
guard let, and
switch, with the former two used more often. The pertinent examples are given below.
Just a couple of notes pertaining to the above code. When we use the
if let statement, we can access the named variable in the immediate curly braces (lines 4-6), but not outside them.
By contrast, when we use the
guard let statement, the named variable can be accessed outside it (line 15), but not in the immediate curly braces (lines 11-13).
switch statement, it’s just because the
Optional data type is a generic enumeration, which thus allows us to check an optional value against the
none case (i.e.,
Sometimes, we’re OK if an optional is
nil and we just don’t perform further operations with the
nil optional. In this case, we can use optional binding by using a post-fix question mark (
?) following the optional variable.
Here’s an example.
As you can tell, both
firstInitial1 variables got created successfully as optional
Booleans with the former being
true and the latter having
In other words, this optional chaining approach allows us to access the optional’s properties and methods safely, because if the optional is
nil, it will just assign
nil to the declared variable.
This is also a very common way to deal with optionals. Basically, we use the nil-coalescing operator (
??) to supply a default value to a declared variable if the optional is
nil. A simple example is given below.
As mentioned before, the data type of accessing a
Dictionary’s element using a key is optional. Depending on the value being
nil or not, the default value after the nil-coalescing operator will be assigned to the declared variable as applicable.
This article reviews various aspects regarding the proper use of optionals in Swift. Here’s a quick summary of takeaways.
Thanks for reading this article. Happy coding in Swift.