Xcode Debugging
Overview
Check build environment BEFORE debugging code. Core principle 80% of "mysterious" Xcode issues are environment problems (stale Derived Data, stuck simulators, zombie processes), not code bugs.
Example Prompts
These are real questions developers ask that this skill is designed to answer:
1. "My build is failing with 'BUILD FAILED' but no error details. I haven't changed anything. What's going on?"
β The skill shows environment-first diagnostics: check Derived Data, simulator states, and zombie processes before investigating code
2. "Tests passed yesterday with no code changes, but now they're failing. This is frustrating. How do I fix this?"
β The skill explains stale Derived Data and intermittent failures, shows the 2-5 minute fix (clean Derived Data)
3. "My app builds fine but it's running the old code from before my changes. I restarted Xcode but it still happens."
β The skill demonstrates that Derived Data caches old builds, shows how deletion forces a clean rebuild
4. "The simulator says 'Unable to boot simulator' and I can't run tests. How do I recover?"
β The skill covers simulator state diagnosis with simctl and safe recovery patterns (erase/shutdown/reboot)
5. "I'm getting 'No such module: SomePackage' errors after updating SPM dependencies. How do I fix this?"
β The skill explains SPM caching issues and the clean Derived Data workflow that resolves "phantom" module errors
Red Flags β Check Environment First
If you see ANY of these, suspect environment not code:
- "It works on my machine but not CI"
- "Tests passed yesterday, failing today with no code changes"
- "Build succeeds but old code executes"
- "Build sometimes succeeds, sometimes fails" (intermittent failures)
- "Simulator stuck at splash screen" or "Unable to install app"
- Multiple xcodebuild processes (10+) older than 30 minutes
Mandatory First Steps
ALWAYS run these commands FIRST (before reading code):
ps aux | grep -E "xcodebuild|Simulator" | grep -v grep
du -sh ~/Library/Developer/Xcode/DerivedData
xcrun simctl list devices | grep -E "Booted|Booting|Shutting Down"
What these tell you
- 0 processes + small Derived Data + no booted sims β Environment clean, investigate code
- 10+ processes OR >10GB Derived Data OR simulators stuck β Environment problem, clean first
- Stale code executing OR intermittent failures β Clean Derived Data regardless of size
Why environment first
- Environment cleanup: 2-5 minutes β problem solved
- Code debugging for environment issues: 30-120 minutes β wasted time
Quick Fix Workflow
Finding Your Scheme Name
If you don't know your scheme name:
xcodebuild -list
For Stale Builds / "No such module" Errors
xcodebuild clean -scheme YourScheme
rm -rf ~/Library/Developer/Xcode/DerivedData/*
rm -rf .build/ build/
xcodebuild build -scheme YourScheme \
-destination 'platform=iOS Simulator,name=iPhone 16'
For Simulator Issues
xcrun simctl shutdown all
xcrun simctl shutdown all
xcrun simctl list devices
xcrun simctl erase <device-uuid>
killall -9 Simulator
For Zombie Processes
killall -9 xcodebuild
ps aux | grep xcodebuild | grep -v grep
For Test Failures
xcodebuild test -scheme YourScheme \
-destination 'platform=iOS Simulator,name=iPhone 16' \
-only-testing:YourTests/SpecificTestClass
Simulator Verification (Optional)
After applying fixes, verify in simulator with visual confirmation.
Quick Screenshot Verification
xcrun simctl boot "iPhone 16 Pro"
xcodebuild build -scheme YourScheme \
-destination 'platform=iOS Simulator,name=iPhone 16 Pro'
xcrun simctl launch booted com.your.bundleid
sleep 2
xcrun simctl io booted screenshot /tmp/verify-build-$(date +%s).png
Using Axiom Tools
Quick screenshot:
/axiom:screenshot
Full simulator testing (with navigation, state setup):
/axiom:test-simulator
When to Use Simulator Verification
Use when:
- Visual fixes β Layout changes, UI updates, styling tweaks
- State-dependent bugs β "Only happens in this specific screen"
- Intermittent failures β Need to reproduce specific conditions
- Before shipping β Final verification that fix actually works
Pro tip: If you have debug deep links (see axiom-deep-link-debugging skill), you can navigate directly to the screen that was broken:
xcrun simctl openurl booted "debug://problem-screen"
sleep 1
xcrun simctl io booted screenshot /tmp/fix-verification.png
Decision Tree
Test/build failing?
ββ BUILD FAILED with no details?
β ββ Clean Derived Data β rebuild
ββ Build intermittent (sometimes succeeds/fails)?
β ββ Clean Derived Data β rebuild
ββ Build succeeds but old code executes?
β ββ Delete Derived Data β rebuild (2-5 min fix)
ββ "Unable to boot simulator"?
β ββ xcrun simctl shutdown all β erase simulator
ββ "No such module PackageName"?
β ββ Clean + delete Derived Data β rebuild
ββ Tests hang indefinitely?
β ββ Check simctl list β reboot simulator
ββ Tests crash?
β ββ Check ~/Library/Logs/DiagnosticReports/*.crash
ββ Code logic bug?
ββ Use systematic-debugging skill instead
Common Error Patterns
| Error |
Fix |
BUILD FAILED (no details) |
Delete Derived Data |
Unable to boot simulator |
xcrun simctl erase <uuid> |
No such module |
Clean + delete Derived Data |
| Tests hang |
Check simctl list, reboot simulator |
| Stale code executing |
Delete Derived Data |
Useful CLI Tools
xcodebuild -showBuildSettings -scheme YourScheme
xcodebuild -list
xcodebuild -verbose build -scheme YourScheme
xcodebuild build-for-testing -scheme YourScheme
xcodebuild test-without-building -scheme YourScheme
xcrun agvtool what-marketing-version
xcrun agvtool what-version
xcrun agvtool next-version -all
xcrun agvtool new-version -all 42
xcrun agvtool new-marketing-version 2.1
xcrun amlint Assets.xcassets
Physical Device Management (devicectl)
devicectl is the modern CLI for physical device operations (replaces legacy idevice* tools).
xcrun devicectl list devices
xcrun devicectl device install app --device <udid> MyApp.app
xcrun devicectl device process launch --device <udid> com.your.bundleid
xcrun devicectl device info apps --device <udid>
xcrun devicectl device info processes --device <udid>
When to use: Physical device debugging when the issue doesn't reproduce in Simulator β install, launch, and inspect from CLI.
Crash Log Analysis
ls -lt ~/Library/Logs/DiagnosticReports/*.crash | head -5
xcrun atos -o YourApp.app.dSYM/Contents/Resources/DWARF/YourApp \
-arch arm64 -l 0x100000000 0x<address>
xcrun crashlog MyCrash.ips
Common Mistakes
β Debugging code before checking environment β Always run mandatory steps first
β Ignoring simulator states β "Booting" can hang 10+ minutes, shutdown/reboot immediately
β Assuming git changes caused the problem β Derived Data caches old builds despite code changes
β Running full test suite when one test fails β Use -only-testing to isolate
Real-World Impact
Before 30+ min debugging "why is old code running"
After 2 min environment check β clean Derived Data β problem solved
Key insight Check environment first, debug code second.