Article

Working with the watchOS App Lifecycle

Learn how the watchOS app lifecycle operates and respond effectively to lifecycle notification methods.

Overview

WatchKit reports changes in your app’s execution state to your extension delegate object. State changes correspond to major events in the lifetime of your app, and the state changes in a Watch app are analogous to the state changes of an iOS app. For each state change, perform relevant tasks, such as loading shared resources and configuring your initial user interface. Table 1 lists the possible state of the app and the implications for your app.

Table 1

Extension states

State

Description

Not running

The watchOS app is not running. The user has not launched the watchOS app, or the system suspended and then purged the app.

Inactive

The watchOS app is running in the foreground, but is not receiving actions from controls or gestures; however, it may be executing other code. A newly launched app usually stays in this state only briefly as it transitions to the active state. An active app that transitions to this state should quiet itself and prepare to transition to the background.

Active

The watchOS app is running in the foreground and receiving actions from controls and gestures. This is the normal mode for apps running on screen.

Background

The system has given the watchOS app a small amount of background execution time. The system gives apps background execution time when running a background session, performing background tasks, and before suspending the app.

Because the system can purge suspended apps without warning, use the exception delegate’s applicationDidEnterBackground() method to save any data you need to recreate your app’s current state. If needed, you can request additional background execution time by calling the ProcessInfo class’s performExpiringActivity(withReason:using:) method.

Suspended

The app is in memory but is not executing code. The system suspends apps that are in the background and do not have any pending tasks to complete. The system may purge suspended apps at any time to make room for other apps. The system silently purges suspended apps. The suspended apps do not wake, and do not receive any notifications before the system purges them.

The system tries to keep frequently used apps in memory, allowing them to resume as quickly as possible. Specifically, the system preserves the most recently executed app, any apps that are in the Dock, and any apps that have a complication on the currently active watch face. If memory constraints force the system to purge one of these apps, the system relaunches the app as soon as more memory becomes available.

Figure 1 shows the state changes that occur for a Watch app and the delegate methods that watchOS calls when those changes occur.

Figure 1

State changes in a Watch app

A figure showing the state changes for a watchOS app.

In Figure 1:

Except for applicationDidFinishLaunching(), the system only calls the extension delegate’s lifecycle methods for the watchOS app’s main interface. It does not call them when the system displays any other supplementary interfaces. For example, they do not occur when the system launches the app to update complications or to display custom notification interfaces. For notifications, use the notification controller’s willActivate() and didDeactivate() methods to track the state of the interface.

Step Through Common State Transitions

The watch app runs in different states depending on the app’s current context. Also, there is no direct relationship between the app’s state and the interface’s state. For example, the app may be inactive while the interface is active. Table 2 shows the app and interface states in most common situations.

Table 2

App and interface states

Situation

App state

Interface state

Running on screen

Active

Active

Running in the dock

Inactive, and the extension’s isApplicationRunningInDock property is true

Active, shown in the dock.

Running as the frontmost app

Inactive

Inactive

Displaying a dynamic notification interface

Inactive or background

Notification interface is active

Processing a snapshot background task

Background

Active, but not shown on screen

Processing another background task

Background

Inactive

Running a background session

Background

Inactive

When transitioning between states, the exact flow depends on the app’s starting and ending conditions, as well as other considerations (for example, if the app has a complication in the current watch face, or if the app is currently the frontmost app, and so on.). Some of the most common transitions include when an app launches, goes to the background, or resumes.

The app launches when it is not running, and the user explicitly starts the app—for example tapping the app icon on the home screen.

  1. The app transitions to the WKApplicationState.inactive state. The system calls the extension delegate’s applicationDidFinishLaunching() method.

  2. The system instantiates the initial interface controller and calls its awake(withContext:) method.

  3. The app transitions to the WKApplicationState.active state. The system calls the extension delegate’s applicationDidBecomeActive() method.

  4. The system calls the initial interface controller’s willActivate() method.

  5. The app appears on screen. The system calls the initial interface controller’s didAppear() method.

The app goes to the background when it is running on screen in the WKApplicationState.active state, and the user lowers their arm or the screen turns off. If the user explicitly closes the app, by pressing the digital crown or covering the screen, the app does not become the frontmost app, and does not remain in the inactive state, but transitions quickly to the background instead.

  1. The system calls the extension delegate’s applicationWillResignActive() method.

  2. The app transitions to the WKApplicationState.inactive state. The app remains in this state as long as it is the frontmost app (by default, 2 minutes).

  3. The app transitions to the WKApplicationState.background state. The system calls the extension delegate’s applicationDidEnterBackground() method.

  4. The system calls the presented interface controller’s didDeactivate() method.

  5. The system suspends the app.

The app resumes when the app is running in the background, or is suspended, and the user activates the app, for example, by tapping its complication on the active watch face.

  1. If suspended but in memory, the app restarts in the WKApplicationState.background state.

  2. The system calls the extension delegate’s applicationWillEnterForeground() method.

  3. The app transitions to the WKApplicationState.active state. The system calls the extension delegate’s applicationDidBecomeActive() method.

  4. The system calls the initial interface controller’s willActivate() method.

Understand Frontmost App State

If your watchOS app is the frontmost app, the system displays it when the user raises their wrist. An app becomes the frontmost app when it is running and the screen turns off or the user drops their arm. The app transitions to the WKApplicationState.inactive state, but does not go to the background.

By default, an app remains the frontmost app for two minutes. Users can configure this behavior using Settings > General > Wake Screen. You can also request additional time as the frontmost app by setting the extension’s isFrontmostTimeoutExtended property to true.

If the user raises their wrist while the app is still the frontmost app, the system automatically activates and displays the app. After the frontmost app state expires, the app transitions to the WKApplicationState.background state and becomes suspended, as normal.

If the user dismisses the app in some other way (for example, by pressing the crown or by covering the screen), the app doesn’t become the frontmost app. Instead, it quickly transitions from the inactive state to the background.

Because the frontmost app is inactive, it is still running in the foreground, even though it is not on screen. This means the app keeps the following features:

  • Can play haptic feedback.

  • Receives notifications.

  • Responds immediately to the completion of a background transfer from a URLSession task or Watch Connectivity session.

For example, when the frontmost app receives a notification, the system calls your notification delegate’s userNotificationCenter(_:willPresent:withCompletionHandler:) method. Rather than displaying the notification alert, your app could play haptic feedback or a custom sound and then update the user interface.

Workout, location, background audio, and audio-recording apps appear to behave similarly to the frontmost app. However, these apps continue to run in the background throughout the entire workout, location, or audio session. If the user navigates to the watch face during a session, the system displays a glyph at the top of the watch face. If the user taps the glyph, the session’s app resumes running in the foreground.

For more information, see HKWorkoutSession.

Receive Background Data

When the system receives background data, it may not immediately wake the watchOS app to process that data. Instead, it may delay delivery of the data to preserve battery life.

If the app is currently running—either active and onscreen, or inactive and the frontmost app—the system immediately delivers the data to the app. If the app is in the background, the system wakes the app within 10 minutes to deliver the data.

See Also

Extension Architecture

class WKExtension

An object that manages behaviors shared by an app’s interface controllers.

protocol WKExtensionDelegate

A collection of methods that manage the app-level behavior of a WatchKit extension.

class WKInterfaceDevice

An object that provides information about the user’s Apple Watch.