What's new in watchOS 8
watchOS 入门 26m

watchOS 8 的新特性

What's new in watchOS 8

2021年6月7日

在 Apple 官方观看视频

一句话判断

watchOS 8 是一次以「生活场景化」为导向的更新——Apple Watch 从运动追踪器变成了家庭健康中枢,但开发者侧的 API 变动幅度不算大。

这场 Session 讲了什么

watchOS 8 带来了几个新的 app 类型:Tips 提供用药提醒记录,Respiratory Rate 在睡眠期间追踪呼吸频率,Portions 用来记录饮食摄入。这些 app 让 Apple Watch 覆盖了更多日常健康管理场景,也让 HealthKit 的数据维度变得更丰富。

对于开发者来说,watchOS 8 的重点在于交互能力的增强。Digital Crown 现在可以用来滚动列表和输入文字,这让原本需要大量依赖 Force Touch 的操作有了更精确的替代方案。Always-On 显示也得到了改进,复杂功能(Complication)可以在息屏状态下展示更多信息。

multitasking(多任务)能力在 watchOS 8 中有提升。App 在后台可以继续运行某些任务,比如网络请求和音频播放。配合新的 SwiftUI API,构建 watchOS app 的体验比以往更加顺畅。

值得深挖的点

Digital Crown 与文字输入的结合

Force Touch 在 watchOS 7 已经被标记为废弃,watchOS 8 进一步用 Digital Crown 的旋转操作替代了长按手势。这个变化意味着开发者需要重新审视所有依赖长按触发功能的交互设计。Digital Crown 配合 SwiftUI 的 digitalCrownRotation 修饰符,可以实现更细腻的滚动和值选择体验。对于表盘复杂功能的数据展示,这种精确控制比 Force Touch 更适合手表的小屏幕。

Always-On 显示的性能考量

Always-On 场景下,系统会把刷新率降到 1Hz 甚至更低。如果你的 Complication 每秒都发起更新请求,电池续航会被迅速消耗。watchOS 8 引入了 TimelineProvider 的刷新策略优化,建议只在数据确实发生变化时才推送更新。这个机制要求开发者在 WidgetKit 的实现中加入更智能的 diff 逻辑。

代码片段

// 使用 Digital Crown 实现滚动选择器
struct CrownPickerView: View {
    @State private var selectedItem = 0
    let items = ["跑步", "骑行", "游泳", "瑜伽"]
    
    var body: some View {
        List(items.indices, id: \.self) { index in
            Text(items[index])
                .font(.title3)
                .padding()
        }
        .focusable()
        .digitalCrownRotation(
            $selectedItem,
            from: 0,
            through: Double(items.count - 1),
            by: 1,
            sensitivity: .medium,
            isContinuous: false,
            isHapticFeedbackEnabled: true
        )
    }
}
// 检测呼吸频率数据
import HealthKit

class RespiratoryRateReader: ObservableObject {
    let healthStore = HKHealthStore()
    
    func fetchLatestRespiratoryRate() {
        guard let sampleType = HKObjectType.quantityType(
            forIdentifier: .respiratoryRate
        ) else { return }
        
        let query = HKSampleQuery(
            sampleType: sampleType,
            predicate: nil,
            limit: 1,
            sortDescriptors: [
                NSSortDescriptor(
                    key: HKSampleSortIdentifierStartDate,
                    ascending: false
                )
            ]
        ) { _, samples, error in
            guard let sample = samples?.first as? HKQuantitySample else { return }
            let rate = sample.quantity.doubleValue(for: HKUnit.count().unitDivided(by: .minute()))
            print("呼吸频率: \(rate) 次/分钟")
        }
        
        healthStore.execute(query)
    }
}
// 为 Complication 提供 Always-On 友好的数据
struct MyComplicationEntry: TimelineEntry {
    let date: Date
    let heartRate: Int
    let isAlwaysOn: Bool  // 标记是否处于 Always-On 模式
}

// 在渲染时根据 isAlwaysOn 调整显示内容
// Always-On 下减少文字、保留关键数字

最佳实践

如果你的 app 支持 watchOS 7 及以上,现在就应该移除所有 Force Touch 相关代码。用 digitalCrownRotation 和长按手势(onLongPressGesture)组合替代。Always-On 场景下的 Complication 更新策略需要配合 reloadTimelines 而非 reloadAllTimelines,只刷新数据确实变化的 Complication。

新加入的 HealthKit 数据类型(呼吸频率、用药记录)需要用户授权,建议在 app 首次启动时用引导流程解释数据用途,而不是一股脑弹出系统权限对话框。

还有什么值得关注

  • watchOS 8 支持将 NFC 标签读取作为后台任务,门禁卡类 app 可以利用这个能力。
  • Portrait 照片现在可以作为表盘背景,配合人像抠图 API 效果不错。
  • 新的 WalletKit 支持更多类型的卡片(车钥匙、酒店房卡),对做出行类 app 的团队是个机会。
WWDC 2021