Understanding The «Unexpectedly found nil while unwrapping an Optional value» Error

Written by: Reinder de Vries, July 3 2017, in App Development

Understanding The «Unexpectedly found nil while unwrapping an Optional value» Error

Optionals are a great feature of Swift, but if you don’t unwrap them safely you’ll run into the Unexpectedly found nil while unwrapping an Optional value error. How can you solve this error?

In this article, you’ll learn about:

  • Optionals and how to use them
  • Fixing the Unexpectedly found nil while unwrapping an Optional value error
  • Safely unwrapping optionals

Understanding optionals, and fixing bugs, is an important part of iOS development. It’s critical to understand optionals as an app developer!

Let’s dive in.

  1. What Is An Optional?
  2. Why Use Optionals?
  3. Force-Unwrapping Optionals
  4. Implicitly Unwrapped Optionals
  5. Safely Unwrapping Optionals
  6. Further Reading

What Is An Optional?

In Swift, Optionals are a special generic type that:

  • can contain a value
  • or no value at all (nil)

A variable can only be nil when it’s an optional. You declare an optional like this:

let meaningOfLife:Int? = 42

The question mark ? at the end of the type declaration denotes that the variable meaningOfLife is an optional. Therefore, this code is OK:

meaningOfLife = nil

The variable meaningOfLife is an optional, so it can be nil.

This example, however, is invalid:

let age:Int = 99
age = nil // This line is not OK

Because age isn’t an optional, it can’t be nil!

Optionals are a powerful feature of Swift, because they make your code safer and less error-prone. As a result, optionals make you more productive as a developer, because you spend less time on fixing bugs.

Get 5 of my best practices

Get 5 of my best practices

Learn how to build better iOS apps

I’ll show you exactly how I built a dozen professional iOS apps,
write extensible Swift code, and turn coffee into code.
Wait, what? Yup – into Swift code.

Why Use Optionals?

But… why do you need optionals?

You already know what variables are. In your app’s code, some variables can have no value at certain times:

  • When a view controller hasn’t been loaded yet, the outlet for textLabel has no value
  • When you get a key-value pair from a dictionary with subscript syntax, like items["food"], the result can have no value, because the key "food" might not exist in the dictionary
  • When you want to access the navigation controller for a view controller with the navigationController property, it can have no value, because the view controller isn’t wrapped in a navigation controller

In Swift, an optional can either have an ordinary value, or be nil. When a variable has no value it is nil.

Almost every programming language has something similar to nil. It’s undefined in JavaScript, null in Java and NULL in PHP. In these languages, to avoid runtime errors with variables that have no value, you have to remember to check if a variable is null. That’s something you could forget…

Swift handles optionals in a special way: it forces the developer to check whether a variable is nil, if it’s an optional. This is called unwrapping. You need to unwrap an optional before you can use it.

When you forgot to unwrap an optional, you’ll find out before your app runs, which saves you time. This makes you more productive, and your code less buggy.

Unlike other languages, Swift will check whether optionals are properly unwrapped at compile-time. So before the app runs, when the code is compiled, Swift will check every optional in your code and see if you’ve properly unwrapped it.

Understanding The «Unexpectedly found nil while unwrapping an Optional value» Error

Unfortunately, some errors can’t be caught by the compiler. That’s when you’ll see this error:

fatal error: Unexpectedly found nil while unwrapping an Optional value

This happens while your app is running, in the following scenarios:

  • You’ve force-unwrapped an optional with !
  • An implicitly unwrapped optional is nil

In 99% of cases you’ve force-unwrapped an optional with ! and it was nil, so that’s the first place to look when you run into this error.

So… to summarize:

  • Optionals are variable types that can either contain a value, or be nil
  • You need to unwrap an optional before you can use it
  • Because you’re forced to check whether a value is nil before running your app, you’re more productive as a developer and your code has less bugs

Build better iOS apps by mastering best practices and app architecture » Find out how

Force-Unwrapping Optionals

The most common scenario for the fatal error: Unexpectedly found nil while unwrapping an Optional value error is when you’ve force-unwrapped an optional and it was nil.

Here’s an example:

let username:String? = "Alice"
let message = "Welcome, " + username!
print(message)
// Output: Welcome, Alice

So far so good… This is what happens in the code:

  1. You create a variable called username. It’s an optional of type String, and it’s assigned the string "Alice"
  2. You create a variable called message, and assign it the value of "Welcome" and username. The optional username is force-unwrapped with !.
  3. You print out the message, and the output is: Welcome, Alice.

Now, let’s assume that this code can run before the user has logged in. When the user hasn’t logged in, username is nil – that’s why it’s an optional.

A login form is presented to the user, but before the user could login the above code already runs. What happens?

let username:String? = nil
let message = "Welcome, " + username!

This is what happens:

fatal error: unexpectedly found nil while unwrapping an Optional value

It’s because you force-unwrapped the optional and it was nil. You could have of course avoided running this piece of code before the user logs in. Most apps however have many moving parts that run independently, and you can’t always avoid that one piece of code runs before or after the other.

How do you solve it? Easy!

let username:String? = nil

if username != nil {
    let message = "Welcome, " + username!    
    print(message)
}

Before you force-unwrap username, you check with an if-statement whether username is nil. When username is nil, the code inside the squiggly brackets { } isn’t executed.

However, there’s a much more elegant way of unwrapping optionals. Read on!

Implicitly Unwrapped Optionals

Another scenario for the Unexpectedly found nil while unwrapping an Optional value error is when you’ve used implicitly unwrapped optionals.

Implicitly unwrapped optionals are optionals that you don’t have to unwrap. Like their name says they’re unwrapped automatically when you use them.

Like this:

let username:String! = "Alice"
let message = "Hello, " + username
print(message)
// Output: Hello, Alice

There’s two things different in this example:

  • username is implicitly unwrapped with the !, after String
  • username doesn’t need to be unwrapped on the second line

Logically, when username is nil the code crashes again:

let username:String! = nil
let message = "Hello, " + username
print(message)

This will output:

fatal error: unexpectedly found nil while unwrapping an Optional value

So why use implicitly unwrapped optionals at all?

  • Some Cocoa Touch SDKs will use implicitly unwrapped optionals. You can find out what the type is of any variable, in Xcode, by clicking on it while holding the Alt-key. Implicitly unwrapped optionals are becoming uncommon in SDKs, though.
  • Sometimes you’ve created a struct or a class, and some of its properties are nil before initializing the class, but will never be nil after. In this case, it saves you quite a bit of code (for unwrapping) if you use implicitly unwrapped optionals. This used to be a convention before Swift 3, but it’s actually equaly convenient and much safer to use optionals and optional binding (more on that later).

If you’re just starting out with coding Swift, it’s recommended to not use implicitly unwrapped optionals unless you have a specific need to do so.

In case you’ve created an implicitly unwrapped optional to avoid the pain of constantly unwrapping variables, then think again – you’re throwing away one of the safest, most powerful, and most productive features of Swift!

Understanding The «Unexpectedly found nil while unwrapping an Optional value» Error https://learnappmaking.com/found-nil-while-unwrapping-optional-valueClick To Tweet

Safely Unwrapping Optionals

The best way to avoid the Unexpectedly found nil while unwrapping an Optional value error is to learn how to safely unwrap optionals.

There’s a 3 ways to unwrap optionals:

  • Force-unwrapping with !
  • Optional binding with if let ...
  • Optional chaining with ?

You’ve already used force-unwrapping. You’d only use force-unwrapping if you’re absolutely certain that the variable will not be nil when you’re accessing it.

If you’re not sure, use optional binding. Say you’ve coded a view controller outlet, like this:

@IBOutlet weak var textLabel:UILabel?

It’s an optional, as denoted by the ?. When you want to use it, for instance in viewDidLoad(), you can use optional binding to unwrap the optional:

if let label = textLabel
{
    label.text = "HOORAY!!"
}

Within the squiggly brackets a constants label is declared, and assigned the value of textLabel. This only happens when textLabel isn’t nil!

In other words, when textLabel is not nil, you’re creating a new constant label, assigning it the value of textLabel, and also executing the code within if-statement. It’s super effective!

Similarly, you can also use optional chaining. Like this:

textLabel?.text = "HOORAY!!"

This code is exactly the same as the example above, but it uses optional chaining instead of optional binding. See the ? after textLabel? When textLabel is nil, the line stops executing. You can’t access the property text on a value that’s nil, so with optional chaining you can avoid that the code continues running.

You can even create an entire chain:

let url = user?.data?.avatar?.url
print(url)

In the above example, url will be nil when either user, data or avatar is nil! You can even combine optional chaining and optional binding:

if let url = user?.data?.avatar?.url
{
    print(url)
}

In the above example, the url constant is only printed when none of the properties are nil.

Get 5 of my best practices

Get 5 of my best practices

Learn how to build better iOS apps

I’ll show you exactly how I built a dozen professional iOS apps,
write extensible Swift code, and turn coffee into code.
Wait, what? Yup – into Swift code.

Further Reading

Optionals can be tough to wrap your head around, but once you understand how to safely unwrap them, you can be sure that you’ll get this error a lot less often:

fatal error: Unexpectedly found nil while unwrapping an Optional value

Here’s what to keep in mind:

  • 99% of the time the above error is caused by a force-unwrapped optional that is nil. You can fix it by avoiding it becomes nil, which is sometimes not possible, so then you use optional binding or optional chaining.
  • Avoid using implicitly unwrapped optionals when you can, unless you have a specific need to use it.
  • Get into the habit of using optionals safely, and your code will have less bugs as a result. Use force-unwrapping, if-statements, optional binding or optional chaining to unwrap optionals.

Want to learn more? Check out these resources:

Enjoyed this article? Please share it!

Understanding The «Unexpectedly found nil while unwrapping an Optional value» Error https://learnappmaking.com/found-nil-while-unwrapping-optional-valueClick To Tweet

Reinder de Vries

Reinder de Vries is a professional iOS developer. He teaches app developers how to build their own apps at LearnAppMaking.com. Since 2009 he has developed a few dozen apps for iOS, worked for global brands and lead development at several startups. When he’s not coding, he enjoys strong espresso and traveling.

Comments & Questions

Got a comment or question? Let me know! I read and respond to every one. Thanks!