Background Processing
Register, schedule, and execute background tasks on iOS using BackgroundTasks (BGTaskScheduler), background URLSession, and background push notifications. Targets Swift 6.3 / iOS 26+.
Contents
Capabilities and Configuration
Every task identifier must be declared in Info.plist under BGTaskSchedulerPermittedIdentifiers, or submit(_:) throws BGTaskScheduler.Error.Code.notPermitted.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.db-cleanup</string>
<string>com.example.app.export.*</string>
</array>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string> <!-- Required for BGAppRefreshTask -->
<string>processing</string> <!-- Required for BGProcessingTask -->
<string>remote-notification</string> <!-- Required for silent push -->
</array>
In Xcode: Target > Signing & Capabilities > Background Modes > enable Background fetch, Background processing, or Remote notifications.
Task Selection Matrix
| Task Type |
Max Duration |
Trigger |
Requires Power/Network |
Use Case |
BGAppRefreshTask |
~30 seconds |
System opportunistic |
Configurable hint |
Light feed/state updates |
BGProcessingTask |
Several minutes |
Device idle |
External power / network optional |
Database cleanup, maintenance, ML indexing |
BGContinuedProcessingTask |
User bounded |
Foreground user action |
Live Activity progress |
Exporting large media, offline bundle generation |
URLSession.background |
Managed out-of-process |
Network completion |
Cellular/WiFi policy |
Large file downloads and uploads |
| Silent Remote Push |
~30 seconds |
APNs trigger (content-available: 1) |
Network required |
Server-driven data invalidation hint |
Core Lifecycle Rules
- Register before launch finishes: Register all handlers in
application(_:didFinishLaunchingWithOptions:) (UIKit) or App.init() (SwiftUI). Submitting an unregistered identifier throws runtime exceptions.
- Re-schedule inside handler: Immediately schedule the next iteration at the beginning of the execution handler so scheduling survives app crashes or task timeouts.
- Always set
expirationHandler: The system can revoke background execution time at any moment. The expiration handler must cancel active tasks and call setTaskCompleted(success: false).
- Call
setTaskCompleted(success:) exactly once: Failing to call completion causes the system to penalize future execution allocations.
- Treat
earliestBeginDate as a lower bound: iOS determines actual launch time based on battery status, power state, and user interaction patterns.
Route by Task
- For full registration code, canonical handlers, and checkpointing, read Canonical Registration and Handlers.
- For simulating task launches with LLDB (
_simulateLaunchForTaskWithIdentifier:), read Debugging Background Tasks.
- For background downloads, uploads, and handling app relaunch in
handleEventsForBackgroundURLSession, read Background URLSession Extended Patterns.
- For background push throttling and payload constraints, read Background Push Extended Patterns.
- For continued processing tasks conforming to
ProgressReporting, read BGContinuedProcessingTask Patterns.
Common Mistakes
- Submitting a task identifier that is not declared in
BGTaskSchedulerPermittedIdentifiers (throws .notPermitted).
- Forgetting to call
task.setTaskCompleted(success:) on all execution and failure paths.
- Omitting
task.expirationHandler, leading to watchdog termination when background time expires.
- Scheduling app refresh at aggressive minute-scale intervals instead of respecting system heuristics.
- Using async/await convenience APIs or completion closures on background
URLSession (requires delegate).
Review Checklist
References
1---2name: background-processing3description: Schedules and executes iOS background work with BGTaskScheduler and background URLSession. Use for app refresh, processing, continued-processing tasks, expiration and completion handling, background downloads, background pushes, registration, Info.plist configuration, or launch simulation.4---56# Background Processing78Register, schedule, and execute background tasks on iOS using BackgroundTasks (`BGTaskScheduler`), background `URLSession`, and background push notifications. Targets Swift 6.3 / iOS 26+.910## Contents1112- [Capabilities and Configuration](#capabilities-and-configuration)13- [Task Selection Matrix](#task-selection-matrix)14- [Core Lifecycle Rules](#core-lifecycle-rules)15- [Route by Task](#route-by-task)16- [Common Mistakes](#common-mistakes)17- [Review Checklist](#review-checklist)18- [References](#references)1920## Capabilities and Configuration2122Every task identifier must be declared in `Info.plist` under `BGTaskSchedulerPermittedIdentifiers`, or `submit(_:)` throws `BGTaskScheduler.Error.Code.notPermitted`.2324```xml25<key>BGTaskSchedulerPermittedIdentifiers</key>26<array>27 <string>com.example.app.refresh</string>28 <string>com.example.app.db-cleanup</string>29 <string>com.example.app.export.*</string>30</array>31<key>UIBackgroundModes</key>32<array>33 <string>fetch</string> <!-- Required for BGAppRefreshTask -->34 <string>processing</string> <!-- Required for BGProcessingTask -->35 <string>remote-notification</string> <!-- Required for silent push -->36</array>37```3839In Xcode: Target > Signing & Capabilities > Background Modes > enable **Background fetch**, **Background processing**, or **Remote notifications**.4041## Task Selection Matrix4243| Task Type | Max Duration | Trigger | Requires Power/Network | Use Case |44|---|---|---|---|---|45| `BGAppRefreshTask` | ~30 seconds | System opportunistic | Configurable hint | Light feed/state updates |46| `BGProcessingTask` | Several minutes | Device idle | External power / network optional | Database cleanup, maintenance, ML indexing |47| `BGContinuedProcessingTask` | User bounded | Foreground user action | Live Activity progress | Exporting large media, offline bundle generation |48| `URLSession.background` | Managed out-of-process | Network completion | Cellular/WiFi policy | Large file downloads and uploads |49| Silent Remote Push | ~30 seconds | APNs trigger (`content-available: 1`) | Network required | Server-driven data invalidation hint |5051## Core Lifecycle Rules52531. **Register before launch finishes**: Register all handlers in `application(_:didFinishLaunchingWithOptions:)` (UIKit) or `App.init()` (SwiftUI). Submitting an unregistered identifier throws runtime exceptions.542. **Re-schedule inside handler**: Immediately schedule the next iteration at the beginning of the execution handler so scheduling survives app crashes or task timeouts.553. **Always set `expirationHandler`**: The system can revoke background execution time at any moment. The expiration handler must cancel active tasks and call `setTaskCompleted(success: false)`.564. **Call `setTaskCompleted(success:)` exactly once**: Failing to call completion causes the system to penalize future execution allocations.575. **Treat `earliestBeginDate` as a lower bound**: iOS determines actual launch time based on battery status, power state, and user interaction patterns.5859## Route by Task6061- For full registration code, canonical handlers, and checkpointing, read [Canonical Registration and Handlers](references/background-task-patterns.md#canonical-bgtaskscheduler-registration).62- For simulating task launches with LLDB (`_simulateLaunchForTaskWithIdentifier:`), read [Debugging Background Tasks](references/background-task-patterns.md#debugging-background-tasks).63- For background downloads, uploads, and handling app relaunch in `handleEventsForBackgroundURLSession`, read [Background URLSession Extended Patterns](references/background-task-patterns.md#background-urlsession--extended-patterns).64- For background push throttling and payload constraints, read [Background Push Extended Patterns](references/background-task-patterns.md#background-push--extended-patterns).65- For continued processing tasks conforming to `ProgressReporting`, read [BGContinuedProcessingTask Patterns](references/background-task-patterns.md#bgcontinuedprocessingtask--extended-patterns).6667## Common Mistakes6869- Submitting a task identifier that is not declared in `BGTaskSchedulerPermittedIdentifiers` (throws `.notPermitted`).70- Forgetting to call `task.setTaskCompleted(success:)` on all execution and failure paths.71- Omitting `task.expirationHandler`, leading to watchdog termination when background time expires.72- Scheduling app refresh at aggressive minute-scale intervals instead of respecting system heuristics.73- Using async/await convenience APIs or completion closures on background `URLSession` (requires delegate).7475## Review Checklist7677- [ ] Task identifiers declared in `BGTaskSchedulerPermittedIdentifiers`78- [ ] Required `UIBackgroundModes` enabled (`fetch`, `processing`, `remote-notification`)79- [ ] Handlers registered during app launch before launch completes80- [ ] `expirationHandler` cancels active tasks and reports failure81- [ ] `setTaskCompleted(success:)` called exactly once on all code paths82- [ ] Subsequent tasks re-scheduled within the handler83- [ ] Background `URLSession` uses delegate and preserves background completion handler84- [ ] Downloaded files moved in `urlSession(_:downloadTask:didFinishDownloadingTo:)` before return85- [ ] Silent pushes include `content-available: 1`, `apns-push-type: background`, and priority 58687## References8889- [Background task patterns and debugging recipes](references/background-task-patterns.md)90- [BGTaskScheduler](https://sosumi.ai/documentation/backgroundtasks/bgtaskscheduler)91- [BGAppRefreshTask](https://sosumi.ai/documentation/backgroundtasks/bgapprefreshtask)92- [BGProcessingTask](https://sosumi.ai/documentation/backgroundtasks/bgprocessingtask)93- [BGContinuedProcessingTask](https://sosumi.ai/documentation/backgroundtasks/bgcontinuedprocessingtask)94- [Performing long-running tasks on iOS and iPadOS](https://sosumi.ai/documentation/backgroundtasks/performing-long-running-tasks-on-ios-and-ipados)