The nil coalescing operator in Swift

Let us focus on this way to avoid Force Unwrapping

There are some techniques that can help the diligent programmer avoid the severe purgatory of force unwrapping. We focus on the nil coalescing operator because of it’s awesomeness and brevity. Let us get ready and…go!

Difficulty: Beginner | Easy | Normal | Challenging

Prerequisites:

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

Terminology

Force unwrapping: Assume that an optional contains a value. Doing this results in a crash if the optional happens to be nil when this is attempted and therefore force unwrapping should only be attempted with the upmost caution.

Optional: 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!

Runtime: The period of time where a program is running

Avoiding Force Unwrapping Optionals

Optionals by definition are either a value, or nil.

Setting up variables

In Swift we can have optionals of various data types, for example Int and String may be optional with the following declarations

var myNum: Int?
var mystring: String?

Now since those declarations above are not initialized, they are both nil.

That is, the following achieves the same for myNum and myString as the code above

var myNum: Int? = nil
var mystring: String? = nil

and the alternative is of course to initialize these variables with a value rather than nil. Something like the following will do:

var myNum: Int? = 1
var mystring: String? = "Test"

The thing is how do we use those values?

The danger of force unwrapping

Force unwrapping consists of using an exclamation mark ! after a variable, and kind of “assumes” that the value stored within the variable is not nil.

An example of this would be to try to print either of the values above without an annoying “Optional” marker being printed to the console.

That is: the following is unsatisfying:

var myNum: Int? = 1
var myString: String? = "Test"
print (myNum) // prints Optional(1)
print (myString) // prints Optional("Test")

Also we have a warning message that indicates something is not quite right (although it is a warning, not an error)

Image for post
Image for post
Oh Dear!

So we can use Force Unwrapping to print the Integer andString without that annoying addition:

var myNum: Int? = 1
var myString: String? = "Test"
print (myNum!) // prints 1
print (myString!) // prints Test

which gets rid of the errors.

Sounds like job done? We don’t have any warnings…

Image for post
Image for post

However the crash comes if either of myNum or myString are nil at runtime. The danger is that because it is at runtime, we have no warning or idea that this is a danger that it might be happening

var myNum: Int? = nil
var myString: String? = nil
print (myNum!) // crash
print (myString!) // crash

Within Playgrounds this looks like:

Image for post
Image for post

Let us be extremely clear, this is unacceptable in production code.

nil coalescing

Instead of Force Unwrapping, you can choose to provide a default value for an optional instead.

var myNum: Int? = nil
var myString: String? = nil
print (myNum ?? "No value set") // prints "No value set"
print (myString ?? "No value set") // prints "No value set"

Effectively the left hand side of the operator ?? is unwrapped, and if it is nil Swift uses the default value on the right hand side of the operator.

This rather moves the challenge to selecting an appropriate default value, but thinking of the choices and options for different cases is a story for another day.

Conclusion

The nil coalescing operator is an option in our toolkit for avoiding nasty Force Unwrapping crashes.

We say to Swift — “Unwrap the value and use it, if it turns out to be nil use this default”. Generally this is succinct and easy to use, a great option for your code!

Further reading

If you’d like a Star Wars themed guide on Force Unwrapping in Swift?

Click the frankly awesome image below:

Image for post
Image for post

Have questions? Hit me up 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