Highlight
iOS 18 和 watchOS 11 带来了一个让人兴奋的变化:你在 iPhone 上创建的 Live Activity,会自动出现在 Apple Watch 的 Smart Stack 中。不需要单独开发 watchOS 版本,不需要管理额外的 push token,系统会自动同步更新。
核心内容
你的 app 已经在 iPhone 上支持 Live Activity 了——锁屏、StandBy、Dynamic Island 都有展示。但用户手腕上的 Apple Watch 呢?在这之前,想让 Live Activity 出现在手表上,你得单独开发一个 watchOS 版本,管理独立的 push token,处理两套更新逻辑。对大多数团队来说,这个成本不值得。
watchOS 11 改变了这件事。升级后,你现有的 iOS Live Activity 会自动出现在 Apple Watch 的 Smart Stack 中。系统用你 Dynamic Island 的 compact leading 和 compact trailing 视图来展示,并在上方标注你的 app 名称。更新也会自动同步到手表——不需要额外的 push token,不需要写新代码。
但这只是起点。compact 视图是为 iPhone Dynamic Island 设计的,直接搬到手表上,文字可能被截断,信息密度也不够。Apple 提供了 supplementalActivityFamilies 修饰符,让你为 Smart Stack 提供专门的视图布局。通过 activityFamily 环境值区分 iPhone 锁屏(.medium)和 Apple Watch Smart Stack(.small),分别给出最合适的界面。
详细内容
自动展示机制
升级到 watchOS 11 后,你的 iOS Live Activity 的 compact leading 和 compact trailing 视图会自动出现在 Smart Stack 中(01:35)。当 iOS 端收到 alerting update 时,如果用户正在看表盘,系统会自动展开 Smart Stack 显示你的更新(02:19)。如果 app 正在前台,屏幕底部会显示一个包含 compact 视图的 banner(02:34)。点击 Live Activity 会进入全屏展示,默认提供”在 iPhone 上打开”选项。
添加 Smart Stack 定制视图
第一步,在 ActivityConfiguration 上添加 supplementalActivityFamilies 修饰符(04:15):
struct DeliveryLiveActivity: Widget {
var body: some WidgetConfiguration {
ActivityConfiguration(
for: DeliveryActivityAttributes.self
) { context in
DeliveryActivityContent(context: context)
} dynamicIsland: { context in
DynamicIsland {
DynamicIslandExpandedRegion(.leading) {
DeliveryExpandedLeadingView(context: context)
}
DynamicIslandExpandedRegion(.trailing) {
DeliveryExpandedTrailingView(context: context)
}
DynamicIslandExpandedRegion(.bottom) {
DeliveryExpandedBottomView(context: context)
}
} compactLeading: {
DeliveryCompactLeading(context: context)
} compactTrailing: {
DeliveryCompactTrailing(context: context)
} minimal: {
DeliveryMinimal(context: context)
}
}
.supplementalActivityFamilies([.small])
}
}
关键点:
.supplementalActivityFamilies([.small])声明你为 Smart Stack 提供了定制视图- 添加后,Smart Stack 不再使用 compact 视图,而是展示
ActivityConfiguration的 content closure 中的视图 - 不加这个修饰符,Smart Stack 默认展示 compact leading + compact trailing
第二步,在 content 视图中用 activityFamily 环境值区分布局(04:49):
struct DeliveryActivityContent: View {
@Environment(\.activityFamily) var activityFamily
var context: ActivityViewContext<DeliveryActivityAttributes>
var body: some View {
switch activityFamily {
case .small:
DeliverySmallContent(context: context)
case .medium:
DeliveryMediumContent(context: context)
@unknown default:
DeliveryMediumContent(context: context)
}
}
}
关键点:
.small对应 Apple Watch Smart Stack.medium对应 iPhone 锁屏@unknown default处理未来可能新增的 family 类型
从 Smart Stack 启动 Watch App
如果你有 Watch App,可以配置点击 Live Activity 时直接打开手表端 app,而不是跳回 iPhone。在 Watch app target 的 Build Settings 中,找到 Info.plist 区域,添加 Supports Launch for Live Activity Attribute Types 键(05:35)。值为空时对所有 Live Activity 生效,也可以指定具体的 ActivityAttributes 类型名。
Always On Display 适配
手腕放下时,系统自动切换为深色配色并降低亮度。用 isLuminanceReduced 环境值来调整亮色元素(08:37):
struct DeliveryGauge: View {
@Environment(\.isLuminanceReduced) private var isLuminanceReduced
var context: ActivityViewContext<DeliveryActivityAttributes>
var body: some View {
Gauge(value: context.state.progressPercent) {
GaugeLabel(context: context)
}
.tint(isLuminanceReduced ? .gaugeDim : .gauge)
}
}
关键点:
isLuminanceReduced为true时表示手腕放下、Always On 模式激活- 此时应移除或降低亮色元素的亮度,保持可读性
- 语义颜色(如
.primary)会自动适配当前配色方案
如果你的 Live Activity 需要浅色外观,在 .small 分支设置 .preferredColorScheme(.light)(08:57)。Always On 模式下系统会自动切换为深色并降低亮度。
更新频率与网络
更新同步是自动的,不需要额外 push token(06:51)。但同步频率受预算限制,阈值与 iOS 类似。如果你目前的 push 更新在 iOS 预算内,Apple Watch 端也不需要额外调整。
网络受限时,系统优先传递 Start、End 和 alerting update(08:01)。Smart Stack 会显示”上次连接”时间,提示用户信息可能不是最新的。手腕抬起时,Live Activity 会刷新为最新可用数据。
核心启发
-
做什么:检查现有 compact 视图的信息密度。为什么值得做:compact 视图会零成本自动出现在手表上,如果只显示静态图标或 app 名称,用户在手表上看到的就是无用的信息。怎么开始:跑一遍你的 Live Activity,看 compact leading/trailing 是否展示了动态变化的关键数据。
-
做什么:用
supplementalActivityFamilies为 Smart Stack 提供定制视图。为什么值得做:compact 视图是为 Dynamic Island 设计的,空间和交互模式与手表不同,定制视图能展示更多信息、提供更好的体验。怎么开始:在ActivityConfiguration上加.supplementalActivityFamilies([.small]),用@Environment(\.activityFamily)分支布局,先从.small场景的简化版开始。 -
做什么:配置 Watch App 直接启动。为什么值得做:用户点击手表上的 Live Activity 时,默认跳到 iPhone app,这打破了手表端的使用闭环。怎么开始:在 Watch app target 的 Info.plist 添加
Supports Launch for Live Activity Attribute Types,值为空即对所有类型生效。 -
做什么:适配 Always On Display。为什么值得做:手腕放下时系统切换深色模式并降低亮度,亮色元素会刺眼甚至烧屏。怎么开始:用
@Environment(\.isLuminanceReduced)检测状态,降低 Gauge、进度条等元素的亮度。
关联 Session
- Broadcast updates to your Live Activities — 用 Broadcast Push Notification 向大量 Live Activity 推送更新
- Bring your app’s core features to users with App Intents — App Intents 框架核心概念:Intents、Entities 与 Queries
- Bring your app to Siri — 用 SiriKit 和 App Intents 把 app 能力暴露给 Siri
- Build custom swimming workouts with WorkoutKit — 用 WorkoutKit 创建和定制健身训练计划
评论
GitHub Issues · utterances