Blog:

Force unwrapping? Don’t do it!

Published on Jul 28, 2017
By Jorg / Software Consultant

When using Swift for the first time, it can be easy to make mistakes with optionals. We’ve seen this happen more than once, even in our own code. Because Swift is becoming increasingly popular, we – Cliff Wings and Tom Eestermans – decided to dedicate a blog to this topic, explaining how to deal with optional in Swift. First, let’s take a look at different types of optional variables.

Optionals: definition and types

We use optionals all the time. These are essentially variables that contain a value or zero (no value). The key difference is the fact that we actually name them in Swift and treat them differently. There are two types of optionals in Swift. These are written as follows:

var  optionalVariableOne : OurClass ?
var  optionalVariableTwo : OurClass !

Looking at the two variables above, we see that they are both optionals. The difference is in the way the compiler deals with them and how you can process this in code.

?

By using the question mark, you can tell the compiler that this variable may be zero and should be dealt with accordingly. It is not possible to approach a variable of this class without safely ‘unwrapping’ it.

!

By using the exclamation mark, you can tell the compiler that this variable could be zero, but that you know for a fact that it has a value. After that, you may no longer can use this variable as if it were not optional.

But what if it does contain a zero? Exactly: app crash at runtime! Not what you want, as a developer. This is not the right approach for most variables. But why?

How not to do it!

The wrong way: quite simply 95% of every instance using an ‘!’. Whether you’re force unwrapping (myClass! .itsVariable) or casting (myClass as! AnotherClass), there is a better way. Knowingly risking an app crash at runtime as a result of encountering a scenario you hadn’t considered during development is something you want to avoid at all costs.

Below, you can find several examples.

Unwrapping

When an object is optional and you want to access one of its methods or properties, you will need to ‘unwrap’ it. There are two ways of doing this, which may also be linked, if you want to move into deeper layers.

optionalObject ?.property?.name
optionalObject !.property!.name

So what’s the difference between these two? When the object you’re trying to unwrap contains a zero value, the ‘?’ will simply return zero and continue. The result of unwrapping with a ‘?’ Will always be an optional. The ‘!’ doesn’t solve this in a neat way, and will make your app crash.

Casting

Casting an object is done with the ‘as’ keyword. When ‘as’ is used without a question mark or exclamation mark, the compiler will issue a warning to the effect that this is not possible. When ‘as’ is used with a question mark or exclamation mark, the compiler will look at it in the way it normally would in the case of optionals.

Let’s discuss a number of methods that can safely produce a non-optional.

Using optionals safely

There are several ways of using optionals safely.

The  if-statement

On possibility is using an ‘if’-statement.

Checking whether the optional contains a nil value allows you to safely use force unwrapping in your code.

if  myClassObject == nil  {

return

}

myClassObject!.itsProperty //Safely accessible

This will work well enough and is fully functional but it does have some disadvantages.

  • You’re checking for a condition that you do not want. Code becomes confusing when it contains this type of check.

To access the properties or methods of your object, you must force unwrap the object, which is exactly what we are trying to avoid!

How about an if-let statement?

let  myOptionalClassObject : MyClass ?
...

if let  unwrapped = myOptionalClassObject as ? MyClass  {

unwrapped.itsProperty //Safely accessible

}

unwrapped.itsProperty //Compiler error, unwrapped not known

This type of if-statement functions like any other, with one exception: the condition is a declaration. As you can see ‘as?’ cast is used, resulting in the cast being stored as a non-optional object of the same type after ‘unwrapping’. If the cast manages to enter the body of the if, it can be used in its unwrapped state. If this fails, it won’t enter into the body.

The downsides of the previous method are, but unfortunately there is another negative effect. You are placing the code you wish to execute in the body of all conditions, instead of behind them.

This might not seem to be a problem, but your code may soon become confusing, when it’s nested in numerous conditions that all need to be successful before you can get your code to run. This method is not ideal as it makes the code unnecessarily complex.

How can we unwrap our optionals without using force unwrapping, whilst maintaining readability and checking for the conditions we would like to see in a safe way?

The way to go!

The way to do this is to first carry out all checks and to return if one of the checks is not successful. This provides a simple and easily understandable way of determine which conditions are required for the proper running of the method. Apparently, this is also called the ‘Bouncer Pattern’, which makes a great deal of sense when you think about it. You want to turn away the bad cases before they can make it through the door. This means you only have to think about one situation at a time. All if this can be done with a guard statement. Like an if-statement, a guard executes code based on the Boolean value of an expression.

The difference is mainly the fact that the guard only executes its body, from which return is obligatory, when the conditions are not met.

var  myOptionalClassObject: MyClass ? = MyClass()
printItsProperty () //This will print true

func  printItsProperty () {

guard let  unwrapped = myOptionalClassObject else  {

//In this case, myOptionalClassObject couldn’t be unwrapped/casted

//unwrapped is also not known in this scope

//here you can safely handle the “crash”

return

}

print(unwrapped.itsProperty) //safely accessible

}

class  MyClass {

var  itsProperty = true

Using a guard solves all three previously mentioned problems:

• You check for the condition you want, instead of the condition you don’t want. When the condition is not met, the else-body of the guard is run, the return of which from the function is mandatory. When the condition is met, the optional variable in this example will be automatically unwrapped within the scope of the guard.

  • you check for bad cases early on, which makes your job easier and easier to read and to maintain.
  • Compile-time checking means you do not accidentally fall through your failsafe when your conditions are not met.

Because you are checking on case-by-case you can also adhere to specific error logging, making debugging considerably easier.
We hope we have been able to convince you of the beauty of the guard statement for unwrapping as well as more important checks.
If you have any questions, don’t hesitate to get in touch.