Optionals in Swift

In this tutorial, we’ll learn how to deal with Optionals in Swift.

What are optionals?

Optionals are Swift Language traits that lets the programmer operate on a variable that may or may not have a value at a particular instance. Usually, this applies to async tasks such as Networking: When you make a request to a server for, say, a list of cat pictures the data in the variable will take some time to arrive. During this loading time if you’d try to access the value within this variable you will crash the application since the value is nil. Another example of this is when you’re trying to construct a URL from a string, you’d have noticed that the variable containing the URL becomes optional because the URL class may or may not be able to construct an URL from the given string. We’ll learn 4 different ways of dealing with optionals and a tip that I use during development.

Various ways of dealing with optionals

  • Force Unwrapping (DO NOT USE THIS)
  • nil coalescing
  • if let
  • guard let (Control Transfer)

Force Unwrapping

This is the most dangerous of all the techniques discussed in this tutorial. Force Unwrapping is the programmer taking responsibility and telling the compiler that they know for sure that some value will exist and in no way when they force unwrap that variable will they get nil. This is dangerous for several reasons. Let us take the URL construction example that we discussed above. If say, you’ve provided a string with htttps:// instead of https:// which can very well happen as a typo and you’ve written this code

let url = URL(string: "htttps://google.com")! //Will Crash your application

This will crash your application as the URL object returned nil since it couldn’t construct a URL with the provided string. This is just the simplest of examples. Force Unwrapping becomes super dangerous in a big production application. When I was starting iOS development and learning the Swift Language I used to force unwrap all the time and then I’d notice Users complaining about the App randomly crashing on them. All because I used ! like way too much.

nil coalescing

This is a sweet little way of dealing with optionals. Nil Colleasing is an operator called using ?? syntax. What this does is in case your value becomes nil it provides some default value that you define to your variable. This means that even if the value initially became nil it’ll still get a default value and therefore the value no longer remains optional. An example can be when you receive data from a JSON service you might have one optional key. You can provide a default value to the right of the nil coalescing operator to convert the optional into a non-optional

let catName = cats["name"].stringValue ?? "Sprinkles" //Get The Office reference? ;)

if let

if let is another technique to deal with optionals. Here the trick is simple, if a non-optional value could be created from an optional then it enters into the if block else it won’t. Let’s understand this with an example

if let catName = cats["name"].stringValue {
    print("Successfully Unwrapped. The Cat name is \(catName)")
}

Here catName is a non-optional because only if the variable could be created as a non-optional does it enter into the if block. When accessing the value inside of the if block use the non-optional, in this case, catName

guard let

Finally, welcome to the world of guard let. Guard let is a control transfer syntax meaning it can transfer the control out of a particular scope. Guard let is useful when you want to escape from a function before it gets too late. guard let works a bit like if let but here if the non-optional value couldn’t be created then the control transfers out of the function. You have to put a return statement inside of the else block because guard statements cannot fall through. You have to either throw an error or return if you’re using the guard let statement.

guard let catName = cats["name"].stringValue else {
    return //If catName couldn't be made, leave the function safely and early.
}

Tip: Assert

This is something that I learnt during my GSoC 2020 with VLC on their iOS project. When using a guard let statement I like to assert if there was an error i.e.: The optional couldn’t be unwrapped into a non-optional value. Assertions cause fatal errors in your code but the catch is that it only becomes a fatalError during DEBUG and not During production. This is excellent because it lets you point out the places your code is breaking forcing you to check the code since the application has crashed. An assertion failure looks something like this

guard let catName = cats["name"].stringValue else {
    assertionFaliure("Couldn't unwrap Cat Name")
    return
}

This helps so much during development that I can’t even tell you. You should use this.

If you liked this article you can

That’s been it. Thank you for reading this and I hope you can now feel better about handling optionals. It’s, according to me, one of the best language traits second only to enums.