Build spatial SharePlay experiences
Spatial Computing 进阶 20m

构建空间 SharePlay 体验

Build spatial SharePlay experiences

2023年6月5日

在 Apple 官方观看视频

一句话判断

空间计算平台的 SharePlay 引入了”共享上下文”和”视觉一致性”两个核心概念——所有参与者看到相同的窗口位置和内容,手指指向的东西其他人也能看到。这不是简单的屏幕共享,是真正的”同处一室”体验。

这场 Session 讲了什么

Session 详细介绍了空间计算平台上 SharePlay 的新范式和 API。

新概念

  • Spatial Persona:参与者的虚拟形象占据物理空间,不再局限于窗口中。
  • 共享上下文(Shared Context):所有人看到彼此和共享窗口的相同相对位置。如果 Connor 指向 Mia 的 Persona,Mia 看到 Connor 指向自己。
  • 视觉一致性(Visual Consistency):所有人看到 App 中的相同内容。如果 Connor 指向方块,Mia 看到的也是 Connor 指向方块,而不是圆圈。
  • 模板(Templates):系统使用模板确定参与者和 App 的空间排列方式。

三种模板

  1. Side-by-Side:参与者在弧线上面向 App。默认模板,适合常规窗口 App。
  2. Conversational:参与者坐半圆,App 在前方。适合音乐播放等非内容聚焦场景。
  3. Surround:参与者围成圆,App 在圆心。只适用于 Volume(三维内容)场景。

System Coordinator: 新 API SystemCoordinator 负责两件事:

  • 接收系统状态(参与者是否为 spatial)。
  • 提供配置选项(模板偏好、isSpatial 标志)。

isSpatial 标志: 决定是否需要同步内容位置。当参与者是 spatial 时(有空间上下文),需要同步滚动位置等;当不是 spatial 时(如普通 FaceTime),不同步这些操作。

场景关联(Scene Association): 多窗口 App 需要告诉系统哪个窗口承载 SharePlay 活动。单窗口 App 自动处理,多窗口 App 如果不设置会随机选择一个窗口。

值得深挖的点

视觉一致性的责任在 App 端。系统提供了空间定位和模板排列,但 App 内部的内容同步需要开发者自己实现。Freeform 的示例展示了”同步滚动位置”的具体做法——当 Connor 滚动文档时,Mia 的文档也同步滚动。这种同步不是自动的,需要通过 GroupSession 的数据通道传递操作指令。

模板选择影响整个体验的空间感。Side-by-Side 适合内容消费类 App(一起看视频),Conversational 适合内容不是焦点的场景(一起听音乐聊天),Surround 适合 3D 内容的协作场景。选错模板会让空间排列感觉不自然——比如用 Surround 放一个 2D 文档窗口会让参与者围着一张纸站圈,很奇怪。

isSpatial 的条件性同步是一个需要仔细处理的细节。同样是 SharePlay 会话,参与者可能有人用空间计算设备(isSpatial = true),有人用普通 iPhone(isSpatial = false)。你的 App 需要根据这个标志决定同步策略——spatial 参与者需要位置同步,非 spatial 参与者不需要。

代码片段

获取 System Coordinator 并配置模板:

import GroupActivities

// 获取 group session 的 system coordinator
let coordinator = await session.systemCoordinator

// 观察 isSpatial 状态
for await state in coordinator.localParticipantState {
    if state.isSpatial {
        // 参与者有空间上下文,需要同步内容位置
        enableContentSync()
    } else {
        // 普通参与者,不需要空间同步
        disableContentSync()
    }
}

// 配置模板偏好(在 join 之前设置)
var config = SystemCoordinator.Configuration()
config.templatePreference = .conversational  // 适合音乐类 App
coordinator.setConfiguration(config)

场景关联(多窗口 App):

// 多窗口 App 需要指定哪个窗口承载 SharePlay
// 单窗口 App 自动处理

// 在 group session 的配置中指定关联的场景
session.join(options: .init(
    // 告诉系统哪个 scene 是 SharePlay 的主场景
    associatedScene: detailWindowScene
))
// 系统会在模板中使用这个指定的窗口
// Share 菜单也会标注哪个窗口正在被共享

条件性内容同步:

// 根据 isSpatial 决定是否同步滚动位置
func handleScrollUpdate(_ position: CGPoint) {
    guard let coordinator = systemCoordinator else { return }

    Task {
        for await state in coordinator.localParticipantState {
            if state.isSpatial {
                // 空间参与者:同步滚动位置
                // 这样当有人指向内容时,其他人能看到指向的位置
                broadcastScrollPosition(position)
            }
            // 非 spatial 参与者:不同步滚动
            break
        }
    }
}

最佳实践

  • 空间 SharePlay 的 App 必须实现视觉一致性——所有参与者看到相同的内容排列。
  • 根据你的 App 类型选择合适的模板:内容消费用 Side-by-Side,音乐/背景体验用 Conversational,3D 内容用 Surround。
  • 多窗口 App 一定要设置场景关联,否则系统可能选错共享窗口。
  • 用 isSpatial 标志决定是否同步内容位置,避免非空间参与者看到意外的 UI 变化。
  • 单窗口 App 不需要处理场景关联,系统自动管理。
  • 模板偏好只在 SharePlay 会话活跃时生效,会话结束后恢复正常布局。

还有什么值得关注

  • “Design spatial SharePlay experiences” Session 详细介绍了共享上下文和视觉一致性的设计原则。
  • Spatial Persona 是空间计算平台独有的概念,普通 FaceTime 不适用。
  • 模板会根据 App 的大小自动调整参与者距离——大 App 远一些,小 App 近一些。
  • Share 菜单会标注哪个窗口正在被共享,避免用户意外操作共享窗口的尴尬。
  • Surround 模板只适用于 Volume 场景,2D 窗口场景只能用 Side-by-Side 或 Conversational。
WWDC 2023