WWDC Quick Look 💓 By SwiftGGTeam
What's new in watchOS 8

What's new in watchOS 8

Watch original video

Highlight

watchOS 8 extends Always-On Display from watch faces to third-party apps. Combined with the isLuminanceReduced environment value and TimelineView, watch apps stay visible when the wrist is down while controlling update frequency and protecting privacy.

Core Content

You built an Apple Watch app. When users raise their wrist, everything works. But when they lower it, the screen either goes black or shows a blurred interface—that was watchOS 7 behavior.

watchOS 8 changes that.

Starting in watchOS 8, third-party apps can stay visible in Always-On state. Apple Watch Series 5 and later support this. Users can glance at app content without raising their wrist.

That raises two immediate questions:

First, how do you design UI at low brightness?

Second, how do you update content when the wrist is down?

Apple answers both with a set of APIs.

Detailed Content

isLuminanceReduced: Sensing Always-On State

02:40

watchOS 8 introduces a new SwiftUI environment property:

@Environment(\.isLuminanceReduced) var isLuminanceReduced

When the watch enters Always-On state, the system automatically lowers screen brightness. isLuminanceReduced becomes true, and your app can adjust UI accordingly.

You can simulate this in Xcode Preview:

ContentView().environment(\.isLuminanceReduced, true)

03:00

Key points:

  • @Environment reads state from the system environment
  • isLuminanceReduced is true at low brightness when the wrist is down
  • Preview and Simulator support simulating this state; the Simulator window has a dedicated button for wrist-down events

The session shows three real apps’ design approaches.

Fitbod keeps interface structure consistent, only dimming secondary text further.

AnyList removes list item background colors, dims secondary info like “Greek yogurt flavor” and “milk quantity,” and makes primary titles stand out.

Pandora removes album artwork, uses dark outlines instead, dims the bottom control bar, and keeps only song title and artist name clearly visible.

03:50

Sensitive information needs handling too. Bank balances and personal health data should be blurred or hidden when the wrist is down. SwiftUI’s .redacted(reason:) modifier shares the same model as widgets.

Animations should reset to the first frame or a static state—don’t pause mid-animation.

TimelineView: Controlling Update Cadence When Wrist Is Down

06:59

Apps with active sessions (like workouts or audio playback) can update UI at most once per second when the wrist is down. Apps without active sessions: at most once per minute.

SwiftUI’s TimelineView handles this timed refresh. It takes a schedule and constructs views over time.

watchOS 8 ships five built-in schedules:

  • EveryMinute: Updates every minute, aligned to the system clock, firing on the minute
  • Periodic: Custom interval, e.g. every two minutes, not aligned to the system clock
  • Explicit: Updates at specified time points, good for precise timing
  • Custom: Mixed strategy, e.g. every minute for 59 minutes, then every second for the last 60 seconds
  • Animation: Animation-specific

07:18

A typical TimelineView usage:

TimelineView(.everyMinute) { context in
    Text(context.date, style: .time)
}

Key points:

  • TimelineView’s closure receives a TimelineViewContext with the current date
  • Without an active session, requesting updates faster than once per minute may be attempted but isn’t guaranteed
  • By default the system returns to the watch face after two minutes, but users can change this in Settings—apps should be ready to stay visible longer

HealthKit Background Delivery

08:58

watchOS 8 brings HealthKit background delivery from iOS to Watch apps. Setup matches iOS:

let query = HKObserverQuery(
    sampleType: heartRateType,
    predicate: nil
) { query, completionHandler, error in
    fetchLatestHeartRateData()
    completionHandler()
}

healthStore.execute(query)
healthStore.enableBackgroundDelivery(
    for: heartRateType,
    frequency: .immediate
) { success, error in
    // Enable background delivery
}

09:13

Key points:

  • HKObserverQuery listens for data changes
  • enableBackgroundDelivery enables background wake
  • Regular apps wake at most once per hour
  • If complications are on an active watch face, up to four times per hour
  • All wake counts count toward the background refresh budget, capped at four per hour
  • Critical data types like fall events, low blood oxygen, and abnormal heart rate deliver immediately
  • Other data types deliver hourly or on longer intervals

The HealthKit authorization form was updated to tell users the app will access health data on Apple Watch more frequently.

Bluetooth Device Background Connection

10:49

watchOS 4 added direct Bluetooth device connection to Apple Watch. watchOS 8’s new capability is connecting during background refresh.

That means complications can continuously fetch data from Bluetooth accessories—e.g. Qardio’s medical-grade ECG or Sonra Watch’s GPS tracker for soccer players.

Background refresh provides at most four connection opportunities per hour, also counting toward the background refresh budget.

Apple added an expiration handler to WKRefreshBackgroundTask:

func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    for task in backgroundTasks {
        task.expirationHandler = {
            // Time running out—clean up connection
        }
        // Connect Bluetooth device, fetch data
    }
}

12:35

Key points:

  • Initial Bluetooth connection must happen in the foreground; background can’t establish new connections
  • After connection is established, background refresh can reconnect to fetch data
  • Data processing must complete quickly
  • expirationHandler lets you wrap up gracefully before time runs out

Region-Based Location Notifications

13:15

watchOS 8 supports UNLocationNotificationTrigger, notifying users when they enter or leave a specified region.

let center = CLLocationCoordinate2D(latitude: 37.7749, longitude: -122.4194)
let region = CLCircularRegion(
    center: center,
    radius: 200,
    identifier: "gym"
)
region.notifyOnEntry = true

let trigger = UNLocationNotificationTrigger(region: region, repeats: false)
let content = UNMutableNotificationContent()
content.title = "Arrived at the gym"
content.body = "Start tracking your workout"

let request = UNNotificationRequest(
    identifier: "gym-entry",
    content: content,
    trigger: trigger
)
UNUserNotificationCenter.current().add(request)

13:40

Key points:

  • CLCircularRegion defines a circular geofence
  • UNLocationNotificationTrigger fires notifications based on region
  • Requires “When in use” location permission
  • Users first receive a static notification; full dynamic content appears after tap, protecting privacy
  • Region radius should be a few hundred meters; only set locations users clearly care about

Core Location’s location button also comes to watchOS. Tapping grants one-time location permission without a prompt every time.

Other System Enhancements

15:18

watchOS 8 also includes notable improvements:

  • Sleep respiratory rate: Apple Watch can measure respiratory rate during sleep; apps read it via HealthKit
  • AssistiveTouch: Gesture recognition helps users with upper-body differences operate the watch
  • Large accessibility text: Larger accessibility text sizes
  • Large titles: Scroll views support iOS-style large titles at the top
  • Text input improvements: Remembers Scribble/dictation preferences per app; quick switching supported
  • Search API: searchable modifier supports custom search suggestions
  • List swipe actions: List items support custom swipe actions (e.g. favorites)
  • Button roles: Distinguish button types (e.g. destructive); control prominence and extra haptics
  • Canvas API: SwiftUI Canvas comes to watchOS for GPU programmatic drawing

Core Takeaways

  1. Build a wrist-down-visible timer app. Use TimelineView + EveryMinute schedule so users see remaining time while cooking or exercising with wrist down. Switch to per-second updates for the last 60 seconds. Entry APIs: TimelineView + Custom schedule.

  2. Build a Bluetooth glucometer complication companion. Connect during background refresh, update the watch face complication hourly. Use expirationHandler to close connections promptly. Entry APIs: CBCentralManager + WKRefreshBackgroundTask.

  3. Build a location-based workout reminder app. Remind users to start logging when they arrive at the gym, save data when they leave. Use UNLocationNotificationTrigger with a 200-meter geofence. Entry APIs: CLCircularRegion + UNLocationNotificationTrigger.

  4. Build a sleep respiratory monitoring dashboard. Use watchOS 8’s new sleep respiratory rate data; show trends each morning. Combine with HealthKit background delivery—no manual refresh. Entry APIs: HKQuantityType (.respiratoryRate) + HKObserverQuery.

  5. Build an Always-On-friendly music player. Hide album art and playback controls when wrist is down; show only song and artist. Use isLuminanceReduced to control UI hierarchy per state. Entry APIs: @Environment(\.isLuminanceReduced) + .redacted(reason:).

Comments

GitHub Issues · utterances