How do you design for the Digital Crown, the always-on display and the watch’s battery and CPU limits?
Predict first
What are the watch application states, and does the Digital Crown modifier compile on watchOS?
import SwiftUI
import WatchKit
print(WKApplicationState.active.rawValue, WKApplicationState.inactive.rawValue, WKApplicationState.background.rawValue)
struct W: View {
@State var d = 0.0
var body: some View { Text("a").focusable().digitalCrownRotation($d) }
}
- 0 1 2
- 1 2 3
- 2 1 0
Mental model. A watch app is a stopwatch, not a spreadsheet: it does one quick thing with a turn of the dial, and the battery is a thimble of water. Anything heavy is done by the phone or the server before you glance down.
Input. The watch has taps and swipes on a small screen, the Digital Crown (a rotating dial with haptic detents, the right control for scrolling, adjusting a value or stepping through items), the side button, the Action button on Ultra and some models (an app can be assigned to it for a primary action) and the double-tap gesture on newer models. In SwiftUI, a view reads the crown with .digitalCrownRotation($value, from:through:by:sensitivity:isContinuous:isHapticFeedbackEnabled:) (the view must be focusable, .focusable(), to receive crown events; the modifier exists on watchOS and is unavailable on tvOS) and long lists scroll with the crown automatically. Design principles: one primary action per screen, large tap targets, short text, no precise gestures, and use haptics (WKInterfaceDevice.current().play(_:)) for confirmation. Always-On display: when the wrist drops, the watch dims and keeps showing the app in a low-power mode with a very limited update rate (about once a second or slower): read @Environment(\.isLuminanceReduced) to redraw with less detail (hide seconds and animation, dim bright colours, show only essential information), because high-contrast, high-motion screens burn battery and OLED. The app’s scenePhase still goes inactive and active as the wrist moves, so keep rendering cheap in every phase, and an app state check reads WKApplicationState as active (0), inactive (1) or background (2).
Battery and CPU. The watch’s CPU, memory and battery are a fraction of the iPhone’s, so never assume phone-class resources: keep work tiny and bursty, avoid long loops and large in-memory models, decode small images, and do heavy processing on the phone or the server. Foreground time is short (the app is suspended soon after the wrist lowers, except during workouts and extended runtime sessions), so make the first screen appear instantly from cached data, and do not start work that cannot finish quickly. Background work is scheduled by the system: request WKApplication.shared().scheduleBackgroundRefresh(withPreferredDate:userInfo:scheduledCompletion:) sparingly (about a few per hour, with the system choosing the moment, and not guaranteed), handle WKApplicationRefreshBackgroundTask and complete every task with setTaskCompletedWithSnapshot, use background URLSession for downloads, and have complications and Smart Stack widgets carry future entries (see the widgets topic). Measure: profile with Instruments (Energy Log and Time Profiler) on a real watch, watch the battery after a day of use, and test cold launch time and the always-on state, since the simulator hides power effects. Remember that wrist-raise launches and complication taps are the dominant entry points, so each must work without the phone and without a network.
The states are active (0), inactive (1) and background (2), and the Digital Crown modifier is available on watchOS.
Common traps
- Assuming the app keeps running after the wrist drops. It is suspended quickly; schedule refresh and show cached data.
- Animating and showing full detail in the always-on state. Check
isLuminanceReducedand simplify the display to save power.
They might follow up with
- How does a SwiftUI view read the Digital Crown? With
digitalCrownRotationon a focusable view. - How should a screen look in the always-on display? Dimmed, simplified and without seconds or animation, using
isLuminanceReduced.
Related questions
- 20.5.2 How do on-watch workouts and health data, and networking directly or through the iPhone, work on watchOS?
- 20.4.2 What input and layout rules define a good tvOS interface: the Siri Remote, controllers, the 10-foot UI, and…
- 19.6.3 How have watch complications moved from ClockKit to WidgetKit, and what are accessory families and the Smart…
How do on-watch workouts and health data, and networking directly or… →