大多数浏览器和
Developer App 均支持流媒体播放。
-
同播共享的新功能
与我们一起体验同播共享的最新更新。我们将向您介绍如何直接从您的 App 启用同播共享,帮助您借助 API 的改进来打造更丰富的体验,并带您了解 GroupSessionMessenger 的增强功能。我们还会讨论将同播共享添加到您的 App 的最佳实践。
资源
相关视频
WWDC23
WWDC22
-
下载
♪ ♪
Adam: 大家好 我是 Adam 同播共享团队的工程师 很高兴能有机会 与大家分享同播共享的更新内容 以及您如何将其 应用到 App 中 我们先来看下从您的 App 启动同播共享的几个新 API 接下来 我们来看一些激动人心的 GroupSessionMessenger 更新 最后是关于实现同播共享体验的 一些最佳实践 从您的 App 中 启动同播共享 我们有求必应 从 iOS 15.4 开始 您可以用新 API 在 App 中启动同播共享 而无需进行 FaceTime 通话 我们来看下是怎样的 现在只需要找到 我们最爱的同播共享 App 比如说音乐 App 找到要同播共享的歌曲 如 Viral Hits 长按 在快捷菜单中 您会看到现在有了一个 新的同播共享按钮 我点击选择 然后跳转到了人物选择器 我们可以选择 Sue 开启一个 FaceTime 通话
如您所见 这里有一个小窗口 显示分阶段活动 如果 Sue 加入了 我们就可以开始 进行群组会话
我认为这是一个很强大的功能 但我们将其分解成更详细的细节
这里 用户可以从分享面板 开启同播共享 您可能会想知道 这个功能需要怎么启用 答案就是 如果您的 App 授权了同播共享 无需额外工作即可 免费获得此按钮 但这并不是最佳的用户体验 因为用户无法通过系统 UI 开启 GroupActivity 相反 还需要重新回到 您 App 的交互界面 选择需要同播共享的功能 那我们来看看您的 App 可以如何应用我们的新 API 答案就是 您只需要在 NSItemProvider 上 注册您的 GroupActivity 然后将 ItemProvider 提供到分享面板
想要保留同播共享按钮 但却不放在显眼位置吗 没问题 您可以用 UIActivityViewController 上的 allowsProminentActivity 来调整行为 只要将 allowsProminentActivity 设置为 false
如果您 App 中有一部分内容 不支持同播共享怎么办呢 虽然我们很希望所有内容 都支持同播共享 您可以通过提示 UIActivityViewController 排除同播共享类型活动 来在分享面板中 隐藏同播共享选项
如果您想直接在您的 App 内 放置一个按钮 那就可以使用我们 新的 API - GroupActivitySharingController 来创建我们的 UIViewController 然后就可以显示了
一旦有人在您的 App 内开启了这种体验 开始了 FaceTime 通话 或者同播共享会话 就会有提示可以激活 分阶段 GroupActivity 激活后 您的 App 就可以 收到 GroupSession 了 如果您在想“等下 Adam 您刚刚说的是” “分阶段 GroupActivity 吗” 不用担心 为什么呢 是的 我确实这么说了 这个想法先放一边 我们稍后讲到最佳实践的时候 再进一步深入讨论 现在 我们先看下在 DrawTogether App 中如何使用
这是我们的 DrawTogether App 也是与之前在 WWDC 2021 “Build custom experiences with Group Activities”讲座里 介绍的 App 是一样的 如果您还没有看过那个讲座 我强烈建议您去看下 如果您已经看过了 就会记得我们的 App 中 是没有任何共享按钮的 但如果您可以发起群组会话 就会有一个同播共享按钮 我们来调整这一行为 这样即使 isEligibleForGroupSession 为 false 现在 也会显示这一按钮来 让用户开启同播共享会话
现在我们可以看下 它是如何运行的了 我们跳转到 ControlBar 代码 现在 如您所见 我们有一个 if 语句 确保没有群组会话 以及我们可以发起群组会话 我们把后面的语句移除 放到下面
现在我们要做的是 注册一个新的变量 这样就知道何时需要显示 我们的 GroupActivitySharingController 所以我们在这里添加一个新的变量 现在我们来处理该变量 变为 true 时的情况
并且我们还需要一个 wrapper 这样可以在 SwiftUI 中 展示 GroupActivitySharingController
最后 我们只需要加入一个 else 语句 如果不能发起群组会话 就将 isSharingControllerPresented 设置为 true
让我们来看看代码的 实际运行效果 我们到 DrawTogether App 中 您可以看到 这里有 同播共享按钮 我们可以点击 出现人物选择器
现在就可以在您的 App 中 体验强大的同播共享功能了 但这并不是我们唯一的更新 现在我们再来看下 GroupSessionMessenger 方面的更新 在 GroupSessionMessenger 中 我们有两个激动人心的更新内容 第一个更新内容 您可能遇到过这个神奇的数字 这是您可通过 GroupSessionMessenger 发送的有效载荷 而这已成往事 我们现在将其提升了四倍 高达 256KB 在这个改变下 您的 App 无需担心 需要把消息拆分成更小的消息 您只用简单地发送消息 专注于搭建完美的体验即可 如果这还不足以让您兴奋 那我们下一个更新内容肯定可以 就是 Unreliable messaging 作为 GroupSessionMessenger 的一部分 您现在可以选择消息的可靠性 这让您可以根据所需的体验 在 reliable 或 unreliable messaging 中进行选择
我们只需要利用 GroupSessionMessenger 中 新的初始化器 允许我们 指定 message reliability
现在我们知道了 应如何使用 API 那体验方面呢 我们什么时候要使用 unreliable messaging 呢 这是一个很好的问题
人们通过 FaceTime 通话 和同播共享来进行实时操作 我们想象下有三个人 Amy Brian 和 Chris 他们加入了一个会话并同步 随着时间的流逝 电影也在进行 但如果 Amy 想要做一些 与他们当下的指定时间内 相关的一些事情怎么办呢 如果您使用 reliable messaging 我们可确保该消息 可在所有设备上收到 但这并不意味着会在他们 预期的时间内收到 例如 Chris 收到了消息 但 Brian 第一次错过了消息 随后也适时收到了 但记住 电影仍在播放 所以现在我们到了 Amy 预期消息能被收到 而 Brian 并未收到的位置 他是在后续的时间收到的 但那时已经太晚了 这是 unreliable 网络的 一个完美例子 它可以告知开发者 什么消息需要在另一端 以可靠的方式收到 而什么消息不需要 在延迟会极大影响用户体验的 情况下 设计协议时 理解这一概念是非常重要的 Unreliable messages 使用的是 UDP 每条消息的延迟和成本更少 这样的话 通过这一方式发送消息 您能获得更即时的体验 现在我们来看下如何在我们的 DrawTogether App 中使用它 您可能还记得 WWDC '21 的 这个屏幕界面 尤其是我画技精湛的笑脸 我们看看您在屏幕上 画这个笑脸的时候 发生了什么事
在我们的 App 中 我们有一些代码 是听从 GestureRecognizer 的 然后每次发送消息的时候 都会有变化 这意味着我们画笑脸的时候 GestureRecognizer 给我们的每个点 都会持续发送新消息 这就太多消息了 现在我们将协议改为 使用 unreliable messaging 获得更无缝衔接的绘画体验
我们在这里所做的是每次从 GestureRecognizer 中 收到一条更新时 就会用 unreliable messaging 发送我们新增的点 一旦手势完成 我们使用 reliable messaging 提供所有点 这样用户可以看到 他们错过的每个点 这让我们可以利用较低的延迟 通过 unreliable messaging 获得更即时的绘制体验 我们看看如何用代码来实现 首先跳转到 我们的 messages 文件
然后定义我们新的 message 类型 如您所见 这个新的 message 类型 和旧的几乎一样 但这次会包含我们笔画的所有点 现在我们跳转到 canvas 文件
我们要设置 一个 handler 函数 来处理即将收到的新消息
然后创建 unreliable messenger 首先 创建一个变量
现在将其初始化
我们会听取结束笔画的消息
将前一条消息 也标记为 unreliable messenger
但我们需要一个发送消息的方式 所以我们上去 finishedStroke
然后开始发送我们的 新消息类型
我们将旧的函数改为 用 unreliable messenger 来发送所有点
现在可以看下代码的运行情况了 跳转到 DrawTogether App 可以看到它是如何无缝衔接的 好了
如我之前所说 我们来讨论下 实现同播共享的 一些最佳实践 您可以记得刚刚我提到一个术语 就是 Staged GroupActivity 这个术语对您的 App 来说 意味着什么呢 让我们来看一个示例场景
假如左边的设备 Adam 和右边的设备 Brian 开启了同播共享 但 Adam 想要继续他们 之前看的节目 所以当有人激活了 staged GroupActivity 时 我们想要跳转到之前节目的 具体时间点 而不是从头开始 这就会带来一个问题 因为 Adam 知道我们的节目 还有 11 分钟未看 但 Brian 的设备不知道 这意味着如果 Brian 的设备 激活 staged GroupActivity 这个节目可能会从头播放 那我们可以怎么办呢 这就要取决于 您的 App 和体验了
我们来看几个想法 在播放的情况下 我们想要每个设备继续其 初始播放状态 其它设备也同样赶上进度 这意味着由于 Adam 的设备 知道播放状态是在 23 秒处 他加入会话时 会告诉其它所有设备 他的预期播放状态 他们会将其作为事实来源 您使用同播共享创建的 所有体验都是同样的原则 每个加入会话的人都应向 其他人提供 他们对会话的理解 因为会话是对等的 无主的 我们再深入看下这一点 无主会话这个概念不好理解 但在设计适宜的同播共享体验时 是非常重要的 在这个情况下 Adam 左边的设备 想要将会话切换到 Apple TV 上 这样他的手机会离开群组会话 而 TV 加入会话 但如果我们应用了所有权 会发生什么呢 所有人离线 所以 记住 这不仅仅是对 TV 而言
在 iOS 16 中 我们现在有了 FaceTime 通话接力 这样 Adam 可以 用 iPad 来接力 是一样的 嘣 这还不是全部 我们只提到了用户流中 将会话从一台设备切换到 另一台设备的案例 但是还有很多其它的案例 好吧 别担心 我们长话短说 只是再多分析一个案例 大家应该很熟悉这个屏幕 这是 FaceTime HUD 但如果我们点击同播共享按钮 会发生什么呢
我们现在能看到一个按钮 End SharePlay 可以让您 … 对的 结束同播共享 这让您可以为所有人 结束同播共享 基本上系统会以 您的 App 的名义 在群组会话中调用 .end() 这意味着不管您多谨慎想着 不要调用 .end() 除非设备是所有者 系统还是会以您的名义 在群组会话中调用 .end() 所以要记住 尽管这个概念 不太好理解 要确保您的 App 没有所有权的概念 这意味着会有更好的使用体验 以上就是讲座的所有内容 您可以在 App 中用新的 API 开启同播共享功能 为您的 App 探索全新的 低延迟的 使用 unreliable messaging 的 通讯方式了
我们很希望能听到大家的声音 所以记得用 Feedback assistant 向我们提出反馈 希望您喜欢我们所做的这些更新 非常期待看到大家搭建的 不可思议的体验 如果您还没有看 记得要查看 我们另一个 WWDC 讲座 “Make a great SharePlay experience” 如果您想看下 我们在媒体播放方面 所做的增强功能 也可以查看 “Display ads and other interstitials in SharePlay” 有任何问题 您可在 GroupActivities labs and challenges 中联系我们 感谢大家的观看 祝大家有一个美好的 WWDC 旅程 我们迫不及待看大家的成果了
-
-
2:06 - Register GroupActivity
// Register GroupActivity let itemProvider = NSItemProvider() itemProvider.registerGroupActivity(WatchTogether()) // Provide the ItemProvider to the ShareSheet let configuration = UIActivityItemsConfiguration(itemProviders: [itemProvider]) UIActivityViewController(activityItemsConfiguration: configuration)
-
2:14 - Not as prominent
let shareSheet = UIActivityViewController(activityItemsConfiguration: configuration) // Show SharePlay non-prominently shareSheet.allowsProminentActivity = false
-
2:15 - Exclude
let shareSheet = UIActivityViewController(activityItemsConfiguration: configuration) // Exclude SharePlay activity shareSheet.excludedActivityTypes = [.sharePlay]
-
2:44 - Show your own button to start SharePlay
let controller = GroupActivitySharingController(WatchTogetherActivity()) present(controller, animated: true)
-
8:21 - Stroke Gesture
var strokeGesture: some Gesture { DragGesture() .onChanged { value in canvas.addPointToActiveStroke(value.location) } .onEnded { value in canvas.addPointToActiveStroke(value.location) canvas.finishStroke() } }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。