What Is an Optional in Swift

Even though Swift is easy to get started with, developers new to the language need to learn several brand new concepts. The most common hurdle developers run into is understanding optionals. What are they? And how should you deal with optionals?

Another common question developers have when they encounter optionals is "Why?" Why are optionals so important in Swift? In this tutorial, we take a close look at optionals.

What Is an Optional

The underlying concept of an optional is easy to grasp. An optional acts as a container for a value of a particular type. The container holds a value or it doesn't.

An optional acts as a container for a value of a particular type. The container holds a value or it doesn't.

Type safety is a cornerstone of the Swift language. As a result, variables and constants need to be initialized before they can be accessed. From a developer perspective, this is amazing because you know that the variable or constant you are accessing has a value. This isn't true in other languages, such as C and Objective-C.

Variables and constants need to be initialized before they can be accessed

But you don't always know what the value of a variable or constant will be. If you fetch data from a remote backend, for example, you don't know whether you are going to receive a valid response until the network request has completed. In such scenarios, you need the ability the represent a different state, the absence of a value. And that is where optionals come into play.

Declaring Optionals

To declare an optional, we use a question mark. In the following example, we declare an optional of type String? or optional String. The question mark indicates that we are dealing with an optional.

var message: String?

Create a playground in Xcode, add the above snippet to your playground, and inspect the output in the results panel on the right. The output should read nil. In Swift, nil means no value or the absence of a value. The meaning of nil in Swift and Objective-C is different. That is very important to understand and remember.

An optional can represent the absence of a value.

Now add the following line of code to your playground and take a look at the output of the print() function on the right. Are you surprised? The output indicates that we are dealing with an optional.

var message: String?
message = "I'll be home at six."
print(message)

The output indicates that we are dealing with an optional.

Unwrapping Optionals

Because the value of an optional is wrapped in a container, you cannot access the value of an optional like you access the value of a variable or constant. The next example illustrates this. Add the following line to your playground.

let body: String = message

The above statement generates an error. Click the red circle on the left to see what the error is about and what Xcode suggests to fix it.

An optional needs to be unwrapped.

Let's give Xcode's suggestion a try by adding an exclamation mark after the name of the optional. That seems to work fine. But what happens if the optional has no value? Update the example as shown below.

var message: String?
let body: String = message!

When the optional message doesn't contain a value, an error is thrown. This time Xcode leaves us out in the cold, not giving any hints to fix the problem.

Treat optionals with caution.

Let's take a moment to discuss what happened and, more importantly, what went wrong. Let me start by explaining the meaning of the exclamation mark. By appending an exclamation mark at the end of an optional, the optional is forced unwrapped. This means that we unwrap the value of the optional's container no matter what it contains. If the optional has a value, we can read the value. If the optional's container is empty, an error is thrown.

Optionals should never be forced unwrapped unless you are absolutely certain it contains a value.

If you force unwrap an optional that doesn't contain a value, your process or application terminates. Optionals should never be forced unwrapped unless you are absolutely certain it contains a value.

Optional Binding

Let's add some safety to the example. Before we assign the value of message to body, it is better to first check if the optional contains a value. That is what we do in the following example.

var message: String?

if message != nil {
    print(message!)
} else {
    print("no value found")
}

This is much safer and we avoid the error we encountered earlier. The downside is that the solution is verbose. We need five lines of code instead of one. Safety comes at a cost.

A more common approach is to use optional binding to safely unwrap the value of the optional. This is illustrated in the next example.

var message: String?

if let unwrappedMessage = message {
    print(unwrappedMessage)
} else {
    print("no value found")
}

Swift inspects the value of message and assigns the value to the unwrappedMessage constant only if message contains a value. The unwrappedMessage constant is then available in the if clause.

If message doesn't contain a value, the else clause is executed. The solution is still verbose, but it is easy to read and understand. Optional binding is very powerful. Take a look at the next example to see a more complex example of optional binding.

var name: String? = "AAPL"
var high: Float? = 110.34
var low: Float? = 99.23

if let name = name, let high = high, let low = low {
    print("\(name): \(high) - \(low)")
}

What's Next?

Optionals are an important concept of the Swift language. Make sure you understand what an optional is and why they exist. They may feel foreign at first, but, over time, you learn to appreciate them.

Stop Writing Swift That Sucks

Download the Swift Patterns I Swear By

About Bart Jacobs

About bart jacobs

My name is Bart Jacobs and I run a mobile development company, Code Foundry. I've been programming for more than fifteen years, focusing on Cocoa development soon after the introduction of the iPhone in 2007.

Stop Writing Swift That Sucks

In my free book, you learn the four patterns I use in every Swift project I work on. You learn how easy it is to integrate these patterns in any Swift project.