Article

Running watchOS Apps in the Background

Schedule and perform background tasks from within your app.

Overview

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

If your app handles background tasks, the app's delegate must implement the WKExtensionDelegate handle(_:) method. watchOS calls this method with a set of tasks for your app to process.

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:

  1. 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 userInfo property set to nil.

  2. After the task completes, the app calls the task’s setTaskCompletedWithSnapshot(_:) method. The system suspends the app again as soon as all background tasks are complete.

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 setTaskCompletedWithSnapshot(_:), 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 CLKComplicationDataSource object’s getNextRequestedUpdateDate(handler:), requestedUpdateDidBegin(), or requestedUpdateBudgetExhausted() methods. Schedule a background app refresh task to update your complication instead.

Request to Schedule a Background Task

Your app can request to run in the background by calling scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:). 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:

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.

See Also

Background Tasks

Playing Background Audio

Enable background audio in your app to provide a seamless playback experience.

Preparing to Take Your watchOS App’s Snapshot

Use snapshot background tasks to provide a timely, accurate snapshot of your app.

class WKRefreshBackgroundTask

The abstract superclass for WatchKit's other background task classes.

class WKApplicationRefreshBackgroundTask

A background task used to update your app’s state in the background.

class WKURLSessionRefreshBackgroundTask

A background task that helps you respond to URLSession background transfers.

class WKWatchConnectivityRefreshBackgroundTask

A background task used to receive background updates from the Watch Connectivity framework.

class WKSnapshotRefreshBackgroundTask

A background task used to update your app’s user interface in preparation for a snapshot.

class WKIntentDidRunRefreshBackgroundTask

A background task used to update your app after a SiriKit intent runs.

class WKRelevantShortcutRefreshBackgroundTask

A background task used to periodically donate relevant Siri shortcuts.

Background Session Keys

Enable background sessions.