How to unwrap Optionals in Swift

Moritz Lang
Slashkeys Engineering
3 min readAug 28, 2016

--

Talking about different solutions for unwrapping optionals.

First things first: What the hell is unwrapping at all?!

Well, in Swift we luckily have a feature called Optionals.
An Optional can either be nil or some value. In the Swift language this is represented by an enum with two cases: None or Some. Optional looks like this:

public enum Optional<Wrapped> : _Reflectable, NilLiteralConvertible {
case None
case Some(Wrapped)
// Some more stuff follows here
}

We can see that the enum has an associated type called Wrapped, which is just a generic placeholder for whatever type we want to use with the Optional enum. Because of that Optionals can declared in many ways:
String? for example is just a shorthand form of Optional<String>. Also nil is just an alias for the enum case .None, which we get through the protocol NilLiteralConvertible.

Unwrapping

Now that you hopefully understand, how to wrap a value inside an Optional, I want to show you how to get it out again. This term is simply called Unwrapping. There are mainly 3 ways of unwrapping an Optional.

Forced unwrapped Optional 🔥

var profileImage: UIImage? = nil
someImageView.image = profileImage!

Never do this!! 👎🏻

What you’ve seen here is an forced unwrapped Optional.
It is very bad coding and extremely unsafe. Instead of testing against nil we say that we are 100% sure that profileImage is not nil. If this wouldn’t be the case our app would crash and our users would be very unhappy. 😥

However, there is a safer way of unwrapping a value using the bang operator.

if profileImage != nil {
someImageView.image = profileImage!
} else {
print("Can't get the image.")
}

Because we first check if profileImage has a value we can then use the exclamation mark to unwrap it. If the value is nil the compiler simply ignores the lines inside the if-block and jump into the else block.

Optional Binding (late exit) 👍🏻

Instead of using the exclamation mark we can bind the unwrapped value to a temporary constant to use it inside a block:

if let profileImage = profileImage {
someImageView.image = profileImage
} else {
print("Can't get the image.")
}

By the way: We can name the temporary constant whatever we want to, but it’s common to use the same name as the variable we want to unwrap. Because the compiler reads the positive clause first it has a late exit.

Guard (early exit) 👍🏻👍🏻

The opposite of the late exit is a guard-statement. Because it’s else clause is written on top it exits early:

guard let profileImage = profileImage else {
print(“Can’t get the image.”)
return
}
someImageView.image = profileImage

Guard statements are much more powerful than the 4 lines we’ve written above, but this is a whole topic of its own.

With that said I want to thank you for reading until the end of this post. If you like this post, please consider a ❤️ or sharing it with the world.

--

--

Moritz Lang
Slashkeys Engineering

Swift Developer / Software Engineering student @codeuniversity