Background Processing Diagnostics
Symptom-based troubleshooting for iOS background task issues. Decision trees for the 7 most common failures, with time-cost analysis for each diagnosis path.
Symptoms This Diagnoses
Use when you're experiencing:
- Background task handler never called despite successful
submit() - Task starts but terminates before completing work
- Background URLSession delegate callbacks never fire
- Tasks work in development with the debugger but fail in production or release builds
- Inconsistent scheduling where tasks run sometimes but not predictably
- App crashes when launched by the system for a background task
- Same task appears to run repeatedly or in parallel
Example Prompts
- "My BGTaskScheduler handler never gets called. What's wrong?"
- "Background task works in Xcode but not for users in production."
- "My background download finishes but didFinishDownloadingTo is never called."
- "Why does my background task get terminated before it finishes?"
- "How do I test background task expiration handling?"
- "My background task scheduling is inconsistent. Sometimes it runs, sometimes not."
- "App crashes when iOS launches it for a background task."
Diagnostic Workflow
30-Second Check
- Info.plist has BGTaskSchedulerPermittedIdentifiers with exact identifier?
- Registration happens in
didFinishLaunchingWithOptionsbeforereturn true? - App not swiped away from App Switcher?
5-Minute Check
- Identifiers match exactly (case-sensitive) between code and Info.plist?
- Background mode enabled (fetch for refresh, processing for processing tasks)?
setTaskCompletedcalled in ALL code paths including errors?- Expiration handler set as first line in handler?
15-Minute Investigation
- LLDB simulate launch triggers handler?
- LLDB simulate expiration is handled gracefully?
- Console shows registration and scheduling logs?
- Testing on real device (not just simulator)?
- Release build matches debug behavior?
- Background App Refresh enabled in Settings?
LLDB Quick Test
text
// Trigger task launch
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.yourapp.refresh"]
// Force expiration
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateExpirationForTaskWithIdentifier:@"com.yourapp.refresh"]Console Log Filter
subsystem:com.apple.backgroundtaskschedulerThe 7 Scheduling Factors
All affect whether iOS runs your task in production:
| Factor | Impact |
|---|---|
| Critically Low Battery | Discretionary work paused below ~20% |
| Low Power Mode | Limited background activity |
| App Usage Frequency | Rarely used apps get lower priority |
| App Switcher | Swiped away = no background until foreground |
| Background App Refresh | User can disable per-app in Settings |
| System Budgets | Depletes with frequent launches, refills daily |
| Rate Limiting | System spaces out launches |
Related
- background-processing — Implementation patterns and decision trees
- background-processing-ref — Complete API reference for all task types
- energy — Battery optimization for background work
Resources
WWDC: 2019-707, 2020-10063
Docs: /backgroundtasks, /backgroundtasks/bgtaskscheduler