My App Crashed, Now What?
- Getting Started
- Tools to Help You Fix and Resolve Crashes
- Console Log
- Variables View
- The Infamous nil
- Exhibit A: Dark Force – Force Unwrapping
- Proving Your Case
- Finding the Right Solution
- Exhibit B: Weak Grip — Weak References
- Understanding the Crash
- Exhibit C: Unexpected Updates — Invalid Table Updates
- A Wider View of the Problem
- Narrowing Down the Problem
- Writing Your Own Reusable Code
- Changing Your Build Configuration
- Where to Go From Here?
App crashes are a natural part of the development cycle. The challenge is to understand the real reason behind the crash and apply the proper fix, not just hide the crash.
In this tutorial, you’ll look at some crash examples, investigate them, understand why they happened and, finally, fix them once and for all.
Before you get started, it’s valuable to know some details about Swift so you understand more about the errors you face:
- Swift uses static typing, meaning the compiler knows the type of a value at compile time.
- It ensures you initialize variables before using them.
- It also notifies you of possible
nilvalues and makes sure you’re aware of how you use them in your code.
You’ll understand more about these points as you fix the project. Now, it’s time to get busy.
Download the starter project for this tutorial by using the Download Materials button at the top or bottom of this page. You’ll find a project called CrashGallery.
The project shows some common scenarios that cause your app to crash. It’s built specifically to demonstrate these scenarios and help you understand them.
The gallery has three exhibits on display with different crash scenarios:
Force Unwrapping: Shows some cases of improper use of
- Weak References: Explains the reference chain in your UI from the storyboard and how you could accidentally break the reference chain and crash the app.
Invalid Table Updates: Shows an example of a common logical discrepancy with
UITableViewthat will crash your app.
You’re going to work through each of these crash scenarios to learn how to find them and how to fix them when you do. But before you start looking at crashes and their causes, take a moment to review three important tools to help you track down crashes when they happen.
Tools to Help You Fix and Resolve Crashes
Pinpointing the cause of a crash can be tricky. Luckily, there are some helpful tools that make this job much easier. Your first step in this tutorial is to get to know three of the most important.
The first handy tool you’ll cover is breakpoints, which make your app pause its execution on a specified line so you can investigate the status of the objects at that point.
To create a breakpoint on any line, simply click on the line number in your source file where you want the execution to stop.
But what if you’re not sure which line you should look at?
Whenever an app that ran from Xcode crashes, the debugger shows you the line that crashed. Sometimes, however, that line won’t be meaningful. There’s another kind of breakpoint that’s handy for situations like this: the exception breakpoint.
The exception breakpoint automatically stops the app when a crash happens and shows you the line that caused it. Now, that’s not always the line you need to fix. The crash might be due to a mistake a few lines earlier, but this line is where the app says “Hey… I can’t proceed anymore.”
To add an exception breakpoint, open the Debug navigator and click the + in the navigator’s lower left corner. Choose Exception Breakpoint… from resulting menu. Click anywhere outside the resulting dialog to set the breakpoint.
The Console Log is at the bottom of the Xcode window. It’ll display plenty of useful logs while the app is running. Whenever your app crashes, you’ll find a log message that contains information on the nature of the crash, whether it was an index out of range exception, a
nil reference or something else.
The log also contains information on warnings, so pay attention to it even if your app isn’t crashing. It could highlight something that can help you make your app better. :]
This window will be completely empty while the app isn’t running. It’ll start showing logs when you run the app.
The third valuable tool for investigating crashes is the Variables View. Similar to the Console Log, it’ll be completely empty when the app isn’t running — but it’ll also stay empty when your app is executing.
The view will only show the values of the variables in the current scope when your execution pauses, which goes hand-in-hand with breakpoints.
The Console Log also shows the values of variables, but the Variables View is more visual and shows you all the variables instead of just one. It’s more useful in many cases, so it’s good to be familiar with both.
Now that you know the tools you need to fix this broken app, build and run the starter app and take a look at the first exhibit.
Swift introduced optionals, which mean an object or an expression may have a value, or it may not. You can’t assume that you’ll always have a value. This is the most common reason for your app to crash.
In the first exhibit, you’ll see some of these situations, but it’s good to understand first what Xcode has to offer to help you identify where your crashes are, what’s happening and why. That’s quite a bit of detective work. :]
Exhibit A: Dark Force – Force Unwrapping
Build and run the app, then open the first item — titled Force Unwrapping — in the gallery screen.
This screen’s task is to compute the sum of the numbers written at the top. The top text view has numbers from the television show “Lost” entered and separated by commas.
The sum of the numbers will appear on the screen when you tap the Calculate button. Give it a shot.
Great, so it works as you intended. Now, play around with it and add
,two at the end of the numbers sequence:
Tap Calculate and see what happens… It crashes.
The crash is in ForceUnwrappingViewController.swift on line number 49. Have a look at what Xcode shows you — there’s a red highlight on the line that triggered the crash.
The Console Log has information on the crash and the Variables View shows the values of
finalValue within the scope of
The value of
"two", so when you converted it to an
Int it failed, giving a
nil value. The force unwrapping by the
! operator caused the crash.