A Practical Guide For Handling Optionals
You may get confused when looking at Swift example code for the first time and noticing all the "?" and "!" you find in the code. It's a concept that's keeps your application more safe from crashing if done correctly. Also, you'll be using it a lot so let us take a deeper dive into it.
This is where optionals in Swift become very powerful. They ensure compile time checks as they simply exist as a type in the type system. Yes, just like we have Int representing an integer, we also have the Int? which is an optional integer. Because of this type, the compiler is able to verify safety and determine when nil must be considered or not.
Think of an optional as a wrapper. They wrap around the content of a variable. And first by unwrapping the optional, we'll find out if the variable is nil or have a value. We define an optional this way:
let myOptional: Int? = nil
The optional above doesn't have a value as we initialised it with nil but later on, we might reassign it. At one point, we need to access the value inside the optional. This action is also known as "unwrapping" the optional. It can be done in various ways which we'll take a look at now.
The first way of accessing the value inside an optional is force unwrapping using the "!" operator but it's very often a bad idea to use this approach. In code, it looks like this:
In the example above, we are absolutely sure that the optional contains a value. But in other cases, there might be a chance where nil is found inside the optional. That will lead to a crash inside our application. There are much safer methods of accessing the value and to avoid a crash. One method for this purpose is called optional binding.
Optional binding using if let
Now, let's look at the optional binding syntax using if let that is much safer than using force unwrapping.
In the example above, we only access the value inside the variable as long as it contains a value which we check using the if let statement. This way we avoid any horrible crashes caused by handling the optional unsafely. It's also possible to unwrap multiple optionals inside the same if-statement using the following syntax as seen in the following code:
In some cases, you may find your code having a pyramid-structure with a lot of indentation using if let inside if let. The approach above of unwrapping multiple optionals can become useful to avoid the pyramid-shape on a smaller scale. But there's another way of doing optional binding to completely eliminate that issue using guard let.
Optional binding using guard let
This is a more preferred style of optional binding using guard let to avoid the pyramid that occurs from using if let statements. Take a look at the example code below:
As you can see, it's simply a different way of doing optional binding. We even avoid the indentation that comes from write our code inside a new if let statement, every time we unwrap an optional.
Sometimes we simply want a default value when the optional turns out to be nil. This can easily be achieved by using the following approach.
We can see that the special "??" operator comes to the rescue. It's a useful trick known as nil coalescing that is very easy to implement in your code. It simply translates to "if the optional is nil, then use zero as the value. If not, use the unwrapped value.
I've got one last trick for you. It's a useful feature called optional chaining that allows you to call any methods or properties on an optional that may or may not be nil. Let's look at the following example:
So in this specific example, we are instantiating the struct Computer which has an optional property processor of the type Processor. This optional property contains the integer property modelNumber. When we decide to access the modelNumber, we use the "?" operator right after our optional property processor (line 17). That way we ask beforehand if the optional processor contains a value, and if so, access the modelNumber.
One thing to note about optional chaining is that the result of optional chaining is always an optional. For this reason it makes sense to unwrap it on the same line using optional binding.
Wrapping up (no pun intended)
In this post, we looked at different ways of handling optionals. Hopefully they seem simple by now (or at least after a little more practice). Bookmark this blog post for now, so you can easily look up how to use them properly. I strongly encourage you to get this under your belt.
Thanks for reading. Remember to leave a comment and share with your fellow developers.
Share this post
You may also like
RxSwift is well known for having a steep learning curve. But taking the time to learn it can easily be the next significant leap in your development abilities. We’ll cover the basic concepts of the library to quickly get you up to speed.
A common frustration with the iOS platform is that resources are accessed using magic strings. In practice, this means you’ll find out if an image, icon, localized string etc. exists at runtime. Either by seeing what you were hoping for or getting a hard crash. Let’s fix this by introducing your new best friend – R.swift.
Defect management should not be a phase in the lifecycle of an app, but instead a fundamental part of an agile process. Here is my recommendation of processes to enforce defect management into your team’s daily workflow.