Avoiding Force Unwrapping in Swift

The Force is only good in Star Wars

You might hear that Force Unwrapping is bad and should be avoided at almost any cost. So what is Force Unwrapping, and why is it important?

Image for post
Image for post
Photo by NeONBRAND on Unsplash

Oh, and this has nothing to do with the Force. I hope nobody gets confused, or if there are confusing Star Wars images within this article.

Difficulty: Beginner | Easy | Normal | Challenging

Prerequisites:

  • Be able to produce a “Hello, World!” iOS application (guide HERE)

Terminology

Compiler: A program that converts the high-level computer program that you write in Xcode, and translates these instructions into machine-code or lower-level form which is executed by the computer

Data Types: The format in which a variable or constant stores data

Optionals: Swift introduced optionals that handle the absence of a value, simply by declaring if there is a value or not. An optional is a type on it’s own!

Image for post
Image for post

An Introduction:

Image for post
Image for post

Optionals are often seen with the Question Mark ? in Swift:

var myString: String?

Which as a data type is either a String or nil.

To demonstrate this, we can declare the String as optional, and print the output without initialising the String.

var myString: String?

var myString: String?
print (myString) // nil
myString = "Hello, World!"
print (myString) // Optional("Hello, World!"
Image for post
Image for post

The optional (?) shows that the compiler cannot be certain if the resultant String is nil or not.

Now for Strings we might not want this to display (for example, we want to just display “Hello, World!” as the text for a label).

One way to avoid this is the titular…

Image for post
Image for post

The issue: Force Unwrapping Strings in Swift

The Poor Option: is Force Unwrap that pesky optional with a quick ! after the String

print(myString!)

Image for post
Image for post

This sounds absolutely fine, since the String has been properly initialised and this therefore not nil.

But if it was, there would be a nasty crash.

How nasty?

Let us create another String, don’t initialise it and then see what happens when we force unwrap it?

It turns out to be really quite nasty.

Image for post
Image for post

In a real Application, this would mean a full crash, that is in iOS you would find that you are dumped back to the Home screen.

Image for post
Image for post

So the fact that you may crash is often considered within organisations and in coding conventions this is seen as completely unacceptable.

Also: you should never do this.

People sometimes do because they copy-pasta (copy paste) code, move code around during refactoring or don’t consider edge cases.

You need to make completely sure that this doesn’t happen to you.

There must be a great solution to this, right?

Using protection

We need to think of ways to safeguard against this problem. Luckily Swift has us covered?

Image for post
Image for post

The implicitly Unwrapped Optional

We use if let to ensure that, if we enact the print command

if let unwrappedString = myCrashingString{
print (unwrappedString) // no output
}
if let unwrappedString = myString {
print (unwrappedString) // "Hello, World"
}
Image for post
Image for post

So if the String is nil, the print function simply is not run. If it has a value, there is no problem and the print function is run.

The guard statement

We have to be a little careful with this. The guard statement is much like the if let pattern, but must be enclosed in a function. For the purposes of this tutorial is increases the complexity of what we are writing, the solution is written below but you might benefit from reading this article about guard statements.

func printString(string: String?) {
guard let unwrappedString = string else {return}
print (unwrappedString)
}
printString(string: myString)

nil coalescing

We can use this simply with a String

print (myString ?? "")

and we can separate out the string from printing

let safeString = myString ?? ""
print (safeString)

The solution that does not apply to types that are not Strings

We can use the nil coalescing operator right in the String with String interpolation:

print (\(myString ?? ""))

Other optionals

You can have many data types that are optionals. Ints, Characters, Arrays, whatever. The same rules apply.

var myChar: Character?
var myInt: Int?
var myFloat: Float?
...

Conclusion…

I’ve already written an article about how optionals may be reimplemented in Swift, but this is kind of a completely different case.

If you go for a job interview, or need to produce production-ready code you will probably be expected to produce code without force unwrapping. There are no ifs, no buts, you are just expected to produce code that is considered to be safe. Safe code is generally that code without force unwrapping.

Perhaps it is time to get used to this…May the Force Be With You!

Want to get in contact? Try the link here:

https://twitter.com/stevenpcurtis

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store