Debugging Swift
Prerequisites: Testing with Swift Testing and XCTest
Debugging is finding out why code doesn't do what you expect.
1. Read compiler errors carefully
Many Swift bugs are caught at compile time. Read the first error in the list — later ones are often caused by it — and look for Xcode's Fix button, which applies the compiler's suggested fix.
2. print and dump
print shows a value; dump shows its full nested structure:
struct User {
let name: String
let tags: [String]
}
dump(User(name: "Ada", tags: ["admin"]))
▿ Shop.User
- name: "Ada"
▿ tags: 1 element
- "admin"
The first line includes the module name — here, Shop.
3. Breakpoints and LLDB
Click the line number gutter in Xcode (or VS Code) to set a breakpoint. When execution reaches it, the program pauses, and you can inspect every variable in the debug area. The debugger console (LLDB) accepts commands:
p totalorpo user— print a value (pouses the object's description).n(next line),s(step into a function),c(continue).bt— the backtrace: how the program got here.
Right-click a breakpoint to add a condition (stop only when
index == 42) or an action that logs a value without stopping.
4. Crash messages
A runtime crash tells you what went wrong and where:
Fatal error: Index out of range
Xcode stops on the failing line; the backtrace shows the calls that led
there. The most common crash causes: force unwrapping nil (!),
indexing past the end of an array, and integer overflow.
5. assert and precondition
Check your own assumptions in code:
func setVolume(_ level: Int) {
precondition((0...10).contains(level), "Volume must be 0-10, got \(level)")
// ...
}
assert(...)— checked only in debug builds.precondition(...)— checked in release builds too.
A failed check stops the program with your message, right where the assumption broke — far easier to debug than bad data surfacing later.
A debugging process
- Reproduce the problem reliably — ideally as a failing test.
- Narrow it down: inspect values halfway through, and keep halving.
- Question assumptions — "this can't be
nil" is often exactly the problem. - Fix it and keep the test, so the bug can't come back.