Schedule and perform background tasks from within your app.
Apps on watchOS primarily run in the foreground in order to limit the impact on system resources. However, there are times an app needs to run even though it is not the foreground app. watchOS allows an app to run in the background in specific instances, such as when:
Your app must perform work while suspended. The system launches or wakes the app up and gives it a small amount of time to run in the background.
The app requests to run in the background because of certain features. Apps that support workouts or audio playback can stay running in the background until the workout or audio playback finishes. If the app uses location services, the system will launch or wake it up in the background when a location update comes in.
A watchOS app uses a background refresh task to perform work in the background. Background tasks give apps a small amount of time (on the order of seconds) to run in the background. If your app requires background operation, you must implement the necessary handler method and perform your action within specific time limits.
Perform a Background Task in Your App
All background tasks follow the same general procedure; first, the system wakes your extension in the background and calls your delegate’s
handle(_:) method. Then the system passes a set containing one or more background tasks. Your app then performs the following actions:
For each task in the set, the app checks the task type, and performs the appropriate actions. If you schedule multiple tasks, provide user info to identify the task’s intended purpose. Tasks scheduled by the system always have their
userproperty set to
After the task completes, the app calls the task’s
setmethod. The system suspends the app again as soon as all background tasks are complete.
Task Completed With Snapshot(_:)
watchOS defines background tasks for specific features that your app may use, such as acquiring snapshots or handing a Siri intent. For more information on the types of watchOS tasks, see WatchKit.
Due to the asynchronous nature of background tasks, your
handle(_:) method may be called with multiple tasks while you are currently handling other background tasks, or while your app is in the foreground. If watchOS calls your
handle(_:) method while your app is in the foreground, you can ignore the tasks, call
set, and return.
If you implement your delegate’s
handle(_:) method, you receive all the background tasks, both those that you schedule and those scheduled by the system. Some of your app’s other behaviors also change:
Background Watch Connectivity transfers wake your app, triggering a background watch connectivity task. Use this task to receive the data and update your app’s state.
Background URLSession transfers wake your app when the transfer needs authorization or when the transfer completes (successfully or not). Use this task to authorize the transfer or to update your app’s state.
The system no longer calls your
Next Requested Update Date(handler:)
Update Did Begin()
requestedmethods. Schedule a background app refresh task to update your complication instead.
Update Budget Exhausted()
Request to Schedule a Background Task
Your app can request to run in the background by calling
schedule. Once your app schedules the task on the preferred date, the system attempts to trigger it no earlier than that date. Depending on the situation, however, the task can be triggered later or even throttled. A task that is throttled will be given less time to run in order to help preserve system resources. Because of this, you shouldn’t expect your app to launch or wake up exactly on time. Also, your app must have an active complication or be docked to receive the background refresh.
Because of the possibility of throttling, do not expect that every background task will be triggered. Have a fallback mechanism so that your app still presents appropriate user interfaces and behaves elegantly if throttling occurs. In the worst case, where your app never receives any background task, it can still update its state next time it runs in the foreground.
Budget Your App's Background Time
The delivery of background tasks and the allocation of background execution time are completely up to the system, and there is no public API to change the behavior. Understanding the limits helps you better design your app’s background update strategy.
When making a watch app, schedule background updates based on the limits, and prepare for background task throttling.
To avoid background tasks abusing the system resources and draining the battery, watchOS implements an algorithm to control how often these tasks can be triggered and how long they can run. The algorithm includes the following restrictions:
Imposing a budget on every watch app. Each app gets an individual allotment of background execution time. A background task can be triggered only when the app has a budget.
Throttling background tasks when the system resources are tight. The system won’t trigger any background task if the device’s battery runs very low or the system conditions are very poor, even though the watch app still has a budget.
Throttling background execution when the user is performing activities, such as working out or navigating.
ClockKit and Watch Connectivity have the following limits:
The complication data source needs to call
completionwithin a certain time limit. Otherwise, ClockKit might backlist the complication data source and not run them anymore.
Current Complication User Info(_:)
WCSessioncan be called a specific number of times per day if your app has an active complication; otherwise, calling the API is not allowed. Check the
remainingproperties before making the call.
Complication User Info Transfers
Budget your app to run for a small amount of time after launches in the background. The app should complete the background task as quickly as possible before exhausting the time allowance. Otherwise, the system will terminate the app, triggering a SIGKILL crash.