Bring your Live Activity to Apple Watch
watchOS 进阶 20m

将 Live Activity 带到 Apple Watch

Bring your Live Activity to Apple Watch

2024年6月10日

在 Apple 官方观看视频

一句话判断

watchOS 11 自动将你的 iOS Live Activity 投射到 Apple Watch Smart Stack,你只需做最少的工作就能让它在手腕上看起来很好——但如果你愿意花时间定制,体验会截然不同。

这场 Session 讲了什么

iOS 18 和 watchOS 11 带来了一个让人兴奋的变化:你在 iPhone 上创建的 Live Activity,会自动出现在 Apple Watch 的 Smart Stack 中。不需要单独开发 watchOS 版本,不需要管理额外的 push token,系统会自动同步更新。

默认情况下,Smart Stack 展示的是你 Live Activity 的 Dynamic Island compact leading 和 compact trailing 两个视图。这意味着如果你之前对 compact 视图投入过精力,现在它们在手表上也能派上用场了。但问题在于,这些视图是为 iPhone Dynamic Island 设计的,直接搬到手表上未必是最佳体验。

好消息是 Apple 提供了一套定制机制。通过 supplementalActivityFamilies 修饰符,你可以为 Smart Stack 提供专门的视图,利用 activityFamily 环境值来区分 iPhone Lock Screen 和 Apple Watch 两种场景,分别给出最合适的布局。

值得深挖的点

自动同步机制与更新预算

Live Activity 的更新从 iPhone 同步到 Apple Watch 是全自动的,这是整个方案最优雅的部分。你不需要为 watchOS 单独维护一套 push 通道,也不需要处理跨设备的状态同步。但自动同步不意味着无限制同步——Apple Watch 有自己的更新预算,阈值和 iOS 侧类似。

这里有一个容易踩坑的地方:如果你在 iOS 端用 ActivityKit 做了大量本地更新(比如频繁刷新外卖配送进度),这些更新会同步到手表并消耗手表侧的预算。超出预算后,手腕放下时可能不会立即显示最新状态,但抬腕时仍然会刷新。对于推送更新已经做得很好的 app 来说,这个预算基本够用,但本地高频更新的场景需要留意。

Always On Display 适配

Apple Watch 在 Always On 模式下会自动切换到深色配色方案并降低亮度。如果你在视图中使用了鲜艳的颜色(比如进度条用了亮红色),需要通过 isLuminanceReduced 环境值检测这个状态,主动降低亮度元素的视觉强度。这不是一个可选项——如果你的 Live Activity 在 Always On 下 readability 很差,用户会在 Smart Stack 中快速把它划走。

代码片段

添加 Smart Stack 支持

在 WidgetConfiguration 上添加修饰符,让 Live Activity 支持 Apple Watch。

// 在你的 ActivityWidgetConfiguration 中添加 supplementalActivityFamilies
@main
struct DeliveryLiveActivity: Widget {
    var body: some WidgetConfiguration {
        ActivityConfiguration(for: DeliveryAttributes.self) { context in
            // Lock Screen 视图
            DeliveryLockScreenView(context: context)
        }
        dynamicIsland: { context in
            DynamicIsland { /* expanded */ }
        } compactLeading: {
            Text("ETA")
        } compactTrailing: {
            Text(context.state.estimatedDelivery)
        }
        // 关键:声明支持 Smart Stack(.small 尺寸)
        .supplementalActivityFamilies([.small])
    }
}

坑:不添加这个修饰符的话,Smart Stack 会 fallback 到 compact leading/trailing 视图,空间利用率很低。

根据 activityFamily 区分布局

利用环境值在同一个视图中为不同设备提供最优布局。

struct DeliveryContentView: View {
    @Environment(\.activityFamily) var activityFamily
    let context: ActivityViewContext<DeliveryAttributes>

    var body: some View {
        switch activityFamily {
        case .small:
            // Apple Watch Smart Stack 布局:精简信息
            HStack {
                VStack(alignment: .leading) {
                    Text("配送中")
                        .font(.caption2)
                    Text(context.state.estimatedDelivery)
                        .font(.title3.bold())
                }
                Spacer()
                Gauge(value: context.state.progress) {
                    EmptyView()
                }
            }
        case .medium:
            // iPhone Lock Screen 布局:完整信息
            DeliveryLockScreenView(context: context)
        @unknown default:
            DeliveryLockScreenView(context: context)
        }
    }
}

适配 Always On Display 的亮度变化

struct StatusGauge: View {
    @Environment(\.isLuminanceReduced) var isLuminanceReduced
    let progress: Double

    var body: some View {
        Gauge(value: progress) {
            EmptyView()
        }
        .gaugeStyle(.accessoryCircularCapacity)
        // 亮度降低时使用更柔和的颜色
        .tint(isLuminanceReduced ? .green.opacity(0.6) : .green)
    }
}

坑:如果你强制设置了 preferredColorScheme.light,系统在 Always On 下会自动切换为 dark appearance 并降低亮度,不需要你手动处理切换逻辑。

最佳实践

已有 Live Activity 的项目: 先确认你的 compact leading/trailing 视图展示的信息是否足够有意义。这是零成本获得 Apple Watch 支持的方式。如果 compact 视图只是展示了一个静态图标或 app 名称,那用户在手表上看到的就是一堆无用信息。第二步再考虑用 supplementalActivityFamilies 提供定制视图。

新项目: 从一开始就把 activityFamily 作为设计约束考虑进去。Lock Screen 视图和 Smart Stack 视图应该一起设计,而不是先做完 iPhone 再硬塞到手表上。如果团队没有 watchOS 开发经验,Live Activity 可能是最低成本的切入点。

有 Watch App 的项目: 可以通过 Info.plist 中的 Supports Launch for Live Activity Attribute Types 配置,让用户点击 Smart Stack 中的 Live Activity 直接打开你的 Watch App,而不是跳回 iPhone。

还有什么值得关注

  • 在 Xcode Preview 中可以直接选择 “Content Smart Stack” 预览模式,不需要真机就能看到手表上的效果
  • 当 Apple Watch 连接不佳时,系统会优先传递 Start、End 和 alerting 类型的更新,其他更新可能延迟,Smart Stack 会显示”上次连接时间”提示用户信息可能过时
  • 即使你没有 Watch App,Live Activity 也能在 Smart Stack 中正常工作,点击后会提供”在 iPhone 上打开”的选项
WWDC 2024