Optional Chaining

Chaining Properties

You will run into this scenario quite often: in order to get the value of a property, you will start with a high level object first and get one of its properties; then get a property of that property object; then go down deep again to get the property of this second level property; and so on. Some times you go could down multiple levels deep.

If you were to check each optional property whether it’s a nil before proceeding down, we would be using multiple levels of if-else optional binding clauses to safely get what we want. This can be become really clumsy and we will see how optional chaining resolves this issue.

Let’s first see a situation where properties can be chained multiple levels deep:

In the above code (going from bottom to top), we have a dictionary that has city code and city object as key-value pairs. Since the city struct has nickname as optional String, we are not providing nickname for NYC.

Forcibly Unwrapping

Let’s say we want to know how many characters are there in the nickname of of a city. String type has a collection called characters (of type CharacterView) which has a count property. This count property gives us the number of characters.

In order to get this character count, we can start from the dictionary to get the appropriate city object, then get the nickname string, and then get characters collection on it and then finally use the count property to get the count of the characters in the nickname string.

We can chain all these properties to get the desired value. In this list, two of them return optional values — dictionary returns optional value (in this case city?) and nickname returns optional string. For these two we need to use ! to unwrap them.

This also crashes, because the dictionary didn’t find the key CHI. So, it returns nil. And we are trying to unwrap a nil and that causes crash.

Safe Unwrapping

Let’s see how we can unwrap safely by using the Optional Binding method discussed before:

// First see if the dictionary has the given city if let city = cities[“SFO”] {

// Then see if the city has a nickname if let nickname = city.nickname {

// Then get the characters and count // No need to unwrap them because they are non-optionals let sfcount = nickname.characters.count } }

As you can see above you would have to use one if-let statement for each of the optionals in the chain. Here it is only two levels deep, but when there are more optionals to go through then getting to the final value safely will have many levels of optional binding.

Optional Chaining

In order to solve the above problem, we can use optional chaining. This is done with the ? operator next to the optional variable (e.g. nickname?). In defining an optional variable we use the ? next to the type (e.g. var nickname: String?). Here we use it next to the variable itself.

So, to safely get the count in the above scenario:

let sfcount = cities[“SFO”]?.nickname?.characters.count

In forced unwrapping we use !, and in optional chaining we use ?. So, what does this mean?

With ? (optional chaining), when Swift encounters a nil, it will return a nil value for the entire expression. It will not crash. In order to accommodate this, the variable sfcount will be an optional of the type that is being returned at the end of the optional chaining.

As you can see above, this value returned from optional chaining is also optional (to accommodate a potential nil value being returned). So, if you want to further use that value safely, you would need to use a pattern like Optional Binding.

But you will use this only one time, as opposed to each time for the optional in the chain:

In this case sfcount can only be used inside the if block. Since we are using the if-let pattern, sfcount will no longer be an optional.

Optional chaining works in a similar way if there are methods or subscripts in the middle which return an optional value. You will need to use ? for the whole expression to safely return nil or non-nil without crashing.