Why am I getting this error?
You are getting this error because you are doing something with an optional value that is nil. The most common reasons for doing something with a nil optional value are the following:
- You have an implicitly unwrapped optional
- You have a disconnected outlet in a storyboard
- You force unwrap an optional
- You use
as!
to cast to a data type
Storyboard outlets are the most common use of implicitly unwrapped optionals.
The textView
outlet has type UITextView!
. Adding the !
character makes the outlet an implicitly unwrapped optional. A disconnected outlet has an empty circle in Xcode’s source code editor, as you can see in the image. Accessing a disconnected outlet crashes your app.
Force Unwrapping Example
The following code demonstrates force unwrapping by getting the contents of a file wrapper:
1 2 |
let data = file.regularFileContents! |
Adding the !
after regularFileContents
force unwraps the optional. If regularFileContents
is nil, setting the data
constant crashes the app.
Avoid force unwrapping because it can crash your app.
as! Example
The following code demonstrates using as!
to cast to a data type:
1 2 3 4 5 6 7 |
func readFont(_ tagData: NSDictionary) -> NSFont? { let fontName = tagData["FontName"] as! String let fontSize = tagData["FontSize"] as! NSNumber let styleFont = NSFont(name: fontName, size: CGFloat(fontSize.floatValue)) return styleFont } |
The function reads font data from a dictionary in a JSON file. The following line of code reads the font name:
1 2 |
let fontName = tagData["FontName"] as! String |
If there isn’t an item in the dictionary with a key named FontName
, the app crashes.
Ways to fix the error
Use guard
statements to exit early if the optional value is nil.
1 2 3 4 5 6 7 |
guard let data = file.regularFileContents else { // Do anything you need to do if data is nil. return } // Do something with data, such as load it |
Use if let
statements to do something only if the optional value is not nil.
1 2 3 4 |
if let data = file.regularFileContents { // Do something with data } |
Use as?
instead of as!
to cast to a specific data type.
1 2 |
let fontName = tagData["FontName"] as? String |
Use the ??
operator to provide a default value if the optional is nil. The following example returns an empty PDF document if you provide a nil URL to create a PDF document:
1 2 |
return PDFDocument(url: fileURL) ?? PDFDocument() |
Check that the optional value is not nil before unwrapping it. This technique is less elegant than the others, but it will prevent the app from crashing.
1 2 3 4 5 |
let data = file.regularFileContents if data != nil { // Do something with data } |
Make sure the outlets in your storyboards are connected. Open the Connections Inspector for the storyboard by choosing View > Inspectors > Connections.
The article Connecting UI Elements has detailed information on connecting outlets.
Additional Reading
Do you want to learn how to fix errors in your Swift code?
I’m writing a book, Fixing Swift Code, that will teach you how to find and fix errors in your Swift code so your projects will build successfully and run without crashing. Some of the things you’ll learn in the book include the following:
- What Xcode’s build error messages really mean
- How to fix your code so your project builds
- How to find where your app crashes
- The most common causes of app crashes and how to fix them
You can learn more about the book and get a discount on the book when it ships by going to the book’s homepage.