大多数浏览器和
Developer App 均支持流媒体播放。
-
利用“信息”提升协作体验
了解如何利用“信息”中的“协作”功能帮助优化 App 的通信和协作。学习如何将文档绑定到“信息”的对话,实现轻松共享和讨论。探索如何让对话中的所有人都能掌握文档中的最新活动。另外,我们还将介绍如何在您的 App 中添加可自定的 UI,以管理协作详情并将文档关联到“信息”对话和 FaceTime 通话。要进一步了解 SharedWithYou 框架,我们建议您观看“在您的 App 中添加‘与您共享'功能”。如需有关为具有自定义协作基础结构的 App 添加协作 API 的更多信息,请观看“集成您的自定义协作 App 到‘信息'”。 (注:即将发布的 Beta 版将提供 API。)
资源
相关视频
WWDC22
WWDC21
-
下载
♪ 柔和乐器演奏的嘻哈音乐 ♪ ♪ Miranda Zhou:嗨 我是 Miranda 我是“共享”团队的工程师 Elana Stettin:我是 Elana 我是一名 “信息”团队的工程师 Miranda:在这个视频中 Elana 和我将深入探讨 如何在您的 App 中 提升与“信息”的协作 我将首先介绍这项功能 您将学习如何为采用这一功能做准备 以及如何将“信息”绑定到流程中 以开始协作 Elana 将解释 如何通过“信息”UI 为您的 App 添加协作 最后 她将探讨如何随时与 协作更新保持同步 首先 让我来介绍一下 与“信息”的协作! 在 iOS 16 和 macOS Ventura 中 我们新增了一种简单方法 来改善协作者之间的沟通 协作者能够借助“信息”的共享功能 将文档结合到对话中 协作活动会出现在“信息”对话 和正在进行的 FaceTime 通话中 可定制的“协作”弹出框 也提供给您的 App 用于管理协作细节 和连接到“信息”对话 这建立在您已使用的技术之上 例如共享表格和拖放 接下来 我将介绍我们 支持的协作基础架构类型 以及如何将其中的每一种 与“信息”协作结合起来 我们支持三种类型的协作基础架构: CloudKit、iCloud Drive 和其他 任何您现在 可能使用的协作基础架构! 在这个视频中 我将集中讲解 使用 CloudKit 和 iCloud Drive 的案例 如果您使用的是自定义基础架构 请观看“将您的自定义协作 App 与‘信息’进行集成” 这一视频获取更多信息 如果您使用 基于 CloudKit 的协作 我们提供了 一个新 API 用于创建 一个系统可识别的协作对象 前提是 macOS Sierra API 用于启动或管理 NSSharingService 的共享 一旦有了协作对象 就请确定在 App 中 显示 UI 的位置 开启或管理共享 您需要升级到新的 API 以增强与“信息”的协作 因为我们将弃用 现有的 AppKit API 新的协作对象 API 使用 NSItemProvider 系统服务使用 NSItemProvider 将您 App 的数据传输到 系统上的其他进程 提供者需要 协作项目的 CKShare 或者需要准备处理器 在协作开始时创建 CKShare 您 App 的 CKContainer 也是必需的 最后 请提供一个 CKAllowedSharingOptions 对象 代表协作的访问和 权限选项 选项的值与 NSCloudKitSharingServiceOptions 相一致 这是此前从 NSCloudSharingServiceDelegate 方法中请求的 这是创建 CloudKit 协作对象 过程的简要概述 如果协作正在启动 并且您传入了 一个准备处理器 您需要同时 创建共享并将其保存到 处理器的服务器中 如果协作已经启动 则只需传入关联的共享 正在注册的 CKAllowedSharingOptions 实例 使用静态标准属性 它将返回默认的允许选项集 CloudKit 采用者可以 使用它 或为一组 受限的允许选项 创建自定义的类实例
如果您对采用 CloudKit 有兴趣的话 CloudKit 让您可以使用 iCloud 作为 App 的数据库 而无需编写自己的服务器代码 您还将获得内置的方法 与其他 iCloud 用户 共享部分数据 如想了解更多信息 请观看“CloudKit 的新功能”视频 如果您使用的 是 iCloud Drive 协作对象就是您的文件 URL 我们将尽全力来识别它! 当这些完成后 请确定您 App 中 开启或管理协作的入口点 并准备好用全新的 改进后的版本进行替换 如果是自定义协作基础架构 协作对象名为 SWCollaborationMetadata 包装在新 NSItemProvider API 中 请观看“将您的自定义协作 App 与‘信息’进行集成”视频 了解更多关于如何使用此 API 更新协作 UI 的信息 现在您已经万事俱备 接下来 开启协作 有两种不同的方式: 一是通过共享表的 新协作模式 二是拖放到“信息” 可以是从您的 App 也可以是从 iOS 上的“文件”App 或 macOS 上的访达 新的共享表协作模式 可以通过标题中的指示器来识别 它也提供了进行协作和 发送一份副本之间的选择 要在共享表中进行协作 请将之前准备的协作对象 提供给共享表 在 macOS 上 这个协作指示器 显示在美观的新共享弹出框中! 共享弹出框还在标题中 包含了名称和图像 并加上了一行对话建议 和我们已提供的所有传输工具 如需了解有关此内容的更多信息 请观看 WWDC 22 的 “AppKit 的新功能”视频 在 iOS 和 Mac Catalyst 上 请使用 UIActivityViewController 类 来显示共享表 在 macOS 上 要显示共享弹出框 请使用 NSSharingServicePicker 请将协作对象作为操作项目 传递给 UIActivityViewController 在启用协作时对它进行展示 同样地 请将 NSSharingServicePicker 与协作对象一同初始化 在启用协作时展示它 CloudKit 采用者 需要额外的步骤 来为标题提供名称和图像 在 iOS 上 可以使用现有的 API 例如 UIActivityItemsConfiguration 或者 UIActivityItemSource 来提供 带有名称和 imageProvider 的 LPLinkMetadata 对象 请使用您的协作对象创建配置 然后设置元数据提供程序返回 共享中项目的 LPLinkMetadata 对象 最后 对 UIActivityViewController 进行使用该配置的初始化操作 在 macOS 上 我们有一个新 API 名为 NSPreviewRepresentingActivityItem 用于提供标题元数据 请参阅 NSPreviewRepresentingActivityItem 文件 了解更多信息 要使用 NSPreviewRepresentingActivityItem 请首先选择名称 图像和图标 图像代表共享中的项目 而图标代表共享中项目的来源 比如说 一个 App 的图标 使用您的协作对象 名称 图像和图标 创建一个 NSPreviewRepresentingActivityItem 并用该预览项对 NSSharingServicePicker 进行初始化 令人兴奋的消息是 新的共享表 SwiftUI ShareLink API 也将支持协作模式! 如需采用 您共享的项目必须由 Transferable 进行表述 它是用于共享和数据传输的新协议 CloudKit 采用者 提供共享容器 和通过 由 Transferable 项返回的 CKShareTransferRepresentation 产出的选项 如需了解详情 请观看 “认识 Transferable”视频 以及 WWDC 22 的 “SwiftUI 的新功能”视频 这个例子将呈现 CloudKit 采用者 比如“备忘录”是如何 创建与 ShareLink 共享的 可转移对象的 note 提供了 CKShareTransferRepresentation 它既可以被构造为具有 现有的 CKShare CKContainer 和 CKAllowedSharingOptions 值的现有值 或者构造为一个 prepareShare 值 它具有 CKContainer CKAllowedSharingOptions 值 以及用于协作对象创建和保存 CKShare 的准备处理器 对于 iCloud Drive 采用者 您的文件 URL 是您通过 ShareLink 共享的 Transferable 对象 如果您使用自定义协作基础架构 请观看“将您的自定义协作 App 与‘信息’进行集成”视频 了解如何从可转移对象返回 SWCollaborationMetadata 对象 一旦有了 Transferable 对象 请将其作为分享项目 传递给 ShareLink 初始化程序 同时 传入带有名称 和图像的预览 用于填写共享表标题 共享表协作模式标题的 一个值得注意的功能 是访问和权限选项摘要 轻点此摘要将打开一个视图 协作者可以在这里 对协作时使用的访问和权限选项 进行选择 对于 CloudKit 采用者来说 这个视图显示的是 在协作对象中注册的选项集 iCloud Drive 采用者 则显示 iCloud Drive 标准选项集 如果您使用自定义基础架构 请观看“将您的自定义协作 App 与‘信息’进行集成”视频 了解如何指定自定义选项 并让它们出现在这个视图中 另一种开启协作的方式 是通过拖放来完成的 协作者可以简单地 将文档拖入“信息”中 并在“信息”中获得新的 可用于协作的富链接 这个富链接提供的功能 既可以用于协作和发送副本 又可以用于选择协作选项 如需采用 请通过 iOS 16 和 macOS Ventura 上的 ShareLink 提供协作对象 这就是您应当如何准备和开启 使用“信息”的协作 接下来 我把时间交给 Elana 她将介绍 如何让您的 App 协作体验 达到新的高度 Elana:谢谢 Miranda! 现在您已经知道该如何入手了 我将谈谈如何进一步将 我们的协作 UI 整合到您的 App 中 我们添加了一些新功能 来增强协作体验 协作按钮 位于您 App 的导航栏中 并会显示关联的 信息组的小组头像 按钮右侧还有活跃参与者计数 会在其他人加入文档时 进行展示 轻点协作按钮时 新的协作弹出框就会出现 可定制的弹出框 展示了协作的概述 它还允许用户发起与其他 与其他参与者的通讯 只需轻轻一点 这使他们能够通过 “信息”和 FaceTime 通话 进行实时协同工作
这些 UI 元素的支持都由一个类 在 SharedWithYou 框架中提供: SWCollaborationView 它代表导航栏中的按钮视图 您需要做的就是初始化 SWCollaborationView 我们会为您完成 弹出窗口布局和展示 要显示自定义内容 您需要提供一个 将被添加到弹出框的视图 现在 我将介绍创建 SWCollaborationView 的代码 请在初始化 SWCollaborationView 时 使用 itemProvider itemProvider 包含 基于 CloudKit 的 App 所用的 CKShare 基于 iCloud Drive 的 App 所用的 fileURL 以及用于自定义协作基础架构的 SW 协作元数据
设置 activeParticipantCount 属性 在 collaborationView 中 来显示 文档中的活跃参与者人数 然后设置 contentView 属性 在 collaborationView 中 来提供 带有自定义内容的弹出框 ContentView 是使弹出框 完全可自定义的原因 您可以在这里添加自己的内容 为用户提供协作进程中的独特视图 例如 在 Pages 文稿中 ContentView 包含 “当前参与者”列表 和“参与者光标”切换按钮 现在 让我们来看看“管理”按钮 对于 CloudKit 和 iCloud Drive 采用者 管理按钮将调出管理 UI 您可以在其中添加和删除参与者 或更改共享设置 稍后我会详细讨论这个问题 如需自定义提供的按钮名称 可以在 collaborationView 中 设置 manageButtonTitle 属性 如果您不设置此属性 名称将默认为“管理共享” 如果您的 App 使用自定义协作基础架构 请在 contentView 中 包含您自己的管理按钮 您将不会得到提供的按钮 在 Mac 上 请确保按钮背景透明 以遵循 Apple 设计建议 最后 在 iOS 上 创建 UIBarButtonItem 如此处所示 使用 collaborationView 作为自定义视图 在 Mac 上 请使用 UIBarButtonItem 来初始化 NSToolbarItem 然后 添加按钮栏项或工具栏项 到 ViewController 的 navigationItem 正如我之前提到的 CloudKit 和 iCloud Drive 采用者 会在协作弹出框中得到一个按钮 这让您能以和过往相同的方式 来对共享进行管理 提供的管理 UI 变化是可观察的 可以通过遵守已经用于观察变化的 相同的委托协议来做到 它们是: UICloudSharingControllerDelegate 和 NSCloudSharingServiceDelegate 现在您已经了解如何将 新的协作 UI 集成到您的 App 中 接下来 我将介绍如何观察和处理 协作的更新 了解共享何时开始和停止至关重要 我们为 CloudKit 采用者 添加了 名为 CKSystemSharing UIObserver 的新协议 专门用于通知共享开始和停止 使用此协议 您可以获取与 CKShare 被保存或删除的时间 相对应的回调 而无需使用 CloudKit Sharing UI 我现在就带您浏览一些代码 请使用 CKContainer 初始化观察器 在观察器上 请定义 CKShare 被保存时 需要执行的闭包 并将它分配到 systemSharingUI DidSaveShareBlock 在闭包中 如果共享被正确保存 您将收到“成功”结果 表示共享已开始 您还将得到供一起 使用的关联 CKShare 如果保存不成功 您将收到“失败”结果 和相关错误说明 这是文档所有者停止共享时 闭包的实现 在“成功”的情况下 CKShare 已被成功删除 在“失败”的情况下 您也会收到相关的错误说明 开始和停止共享 可能并不是您关心的唯一变化 有些变化 您甚至会想向用户传达 我们添加让您可以发布通知 总结协作更新的 API 通知就位于相关“信息”线程的顶部 它为协作者展示了更新内容 以及改变的发起者 如需发布通知 请检索 SWCollaborationHighlight 这是 SharedwithYou 中 一个协作指定的亮点类型 请使用它来创建一个 SWCollaborationHighlight 事件 如想了解有关 SWHighlights 和 SharedWithYou API 的更多信息 请观看“在您的 App 中 添加 SharedwithYou”视频 请在开始进行通知的采纳之前 观看此视频 我将以一个 CloudKit App 为例 来介绍不同通知的发布 如果您的 App 使用自定义协作基础架构 请观看“将您的自定义协作 App 与‘信息’进行集成”视频 获取详细说明 为了表述通知 我们引入了一个 名为 SWHighlightEvent 的协议 亮点事件的初始化是由 从 SWHighlightCenter API 检索的 SWHighlights 进行的 支持的事件类型包括更改事件 用于内容更新或评论 提及事件 用于在协作中提及用户 持续事件 用于内容 被移动 重命名或删除时 还有成员事件 用于在文档中添加或删除参与者时 这个例子展示了如何在 协作被编辑时发布更改事件 借助 highlightCenter API 使用 CKShare URL 检索协作亮点 请记住 这个 CKShare 是您在 协作初始化时定义的 因此您的 App 应该使它 在进行内容更改时可用 接下来 创建 HighlightChangeEvent 实例 初始化程序需要一个亮点 和一个触发器枚举值 在这种情况下 我们将 触发器类型设置为编辑 最后 发布该事件的通知 到 highlightCenter 其他事件都遵循类似的格式 唯一的例外是提及事件 因为它需要更多信息 来指示是哪个用户受到了提及 发布此类事件的前提是 您的 App 支持用户提及 通过传入检索到的亮点和 提及的 CKShare 参与者的句柄 来创建 mentionEvent 此通知将仅显示给受到提及的用户 持续事件类型用于内容发生移动 重命名或删除时 在这里使用了重命名的 触发器类型来表明 文档名称已更改 最后来看一个成员事件 对于 membershipEvent 则需要使用 addedCollaborator 或 removedCollaborator 触发器类型 使用 mentionevents 就可以发布通知显示 文档的协作成员发生了怎样的变更 不过 我们也保留了让协作者 在您的共享文档上同步了解 “信息”群组成员变更的可能性 对于 CloudKit 和 iCloud Drive 来说非常简单 我们将替您完成这些工作 添加新成员到存在协作的 “信息”群组时 文档所有者 从通知得到提示 可以将其添加到共享中 当成员被移除时也是这样
对于使用自定义 协作基础架构的 App 来说 还需要多做一些工作 您将需要采用 SWCollaborationActionHandler API 您可以 在“将您的自定义协作 App 与‘信息’进行集成”视频中 了解更多信息
您已经了解 如何在“信息”中开启协作 并将其集成到您的 App 中 无论是使用 CloudKit iCloud Drive 还是 您自己的协作基础设施 通过采用新的共享表和拖放 API 来为您的 App 开启协作做好准备 集成新的协作 UI 来为共享文档中的事件 提供定制化的概览 将它设置好之后 再向前一步 采用通知来显示 “信息”线程内对协作进行的更改 Miranda 和我都等不及 想看看您的 App 如何使用 “信息”中的这些新协作功能了! 两位:感谢收看! ♪
-
-
4:08 - Create a CloudKit collaboration item provider
// CloudKit collaboration object // Starting collaboration let itemProvider = NSItemProvider() itemProvider.registerCKShare(container: container, allowedSharingOptions: CKAllowedSharingOptions.standard, preparationHandler: { // Create your share and save to server, or throw error return savedShare }) // Inviting to existing collaboration let itemProvider = NSItemProvider() itemProvider.registerCKShare(share, container: container, allowedSharingOptions: CKAllowedSharingOptions.standard)
-
7:35 - Set up Share Sheet on iOS and Mac Catalyst
// Setting up Share Sheet - iOS and Mac Catalyst let activityViewController = UIActivityViewController(activityItems: [collaborationObject], applicationActivities: nil) presentingViewController.present(activityViewController, animated: true)
-
7:47 - Set up Share Popover on macOS
// Setting up Share Popover - macOS let sharingServicePicker = NSSharingServicePicker(items: [collaborationObject]) sharingServicePicker.show(relativeTo: view.bounds, of: view, preferredEdge: .minY)
-
8:22 - Provide metadata for CloudKit collaboration in Share Sheet (iOS, Mac Catalyst)
// Providing CloudKit metadata - iOS let configuration = UIActivityItemsConfiguration(itemProviders: [collaborationItemProvider]) configuration.perItemMetadataProvider = { (_, key) in switch key { case .linkPresentationMetadata: // Create LPLinkMetadata with title and imageProvider return metadata default: return nil } } let activityViewController = UIActivityViewController(activityItemsConfiguration: configuration)
-
9:03 - Provide metadata for CloudKit collaboration in Share Popover (macOS)
// Providing CloudKit metadata - macOS let title = “Shared Item” let image = NSImage(contentsOfFile: “Shared_Item_Preview_Image.png”) let icon = NSImage(contentsOfFile: “App_Icon.png”) // Shared item source let previewRepresentingItem = NSPreviewRepresentingActivityItem(item: collaborationItemProvider, title: title, image: image, icon: icon) let picker = NSSharingServicePicker(items: [previewRepresentingItem])
-
10:21 - Create Transferable object for CloudKit collaboration with ShareLink
// SwiftUI CloudKit Transferable struct Note: Transferable { // Properties of the note e.g. name, preview image, content, ID, … var share: CKShare? func saveCKShareToServer() async throws -> CKShare { … } static var transferRepresentation: some TransferRepresentation { CKShareTransferRepresentation { note in if let share = note.share { return .existing(share, container: container, options: options) } else { return .prepareShare(container: container, options: options) { return try await note.saveCKShareToServer() } } } } }
-
11:34 - Adopt ShareLink in SwiftUI
// SwiftUI ShareLink adoption struct ContentView: View { @State let item = ShareItem() var body: some View { ShareLink(item: item, preview: SharePreview(item.title, image: item.previewImage)) } }
-
14:58 - Initialize the collaborationView
// Collaboration View let collaborationView = SWCollaborationView(itemProvider: itemProvider) collaborationView.activeParticipantCount = myModel.activePeople.count collaborationView.contentView = MyView(model: myModel) collaborationView.manageButtonTitle = "Custom Manage Button"
-
18:11 - Observe when CKShare is saved with CKSystemSharingUIObserver
// Observing CKShare Changes let observer = CKSystemSharingUIObserver(container: container) observer.systemSharingUIDidSaveShareBlock = { _, result in switch result { case .success(let share): // Handle successfully starting share case .failure(let error): // Handle error } }
-
18:47 - Observe when CKShare is removed with CKSystemSharingUIObserver
// Observing CKShare Changes observer.systemSharingUIDidStopSharingBlock = { _, result in switch result { case .success(let share): // Handle successfully starting share case .failure(let error): // Handle error } }
-
20:44 - Posting notice for edit SWHighlightChangeEvent
// Post an SWHighlightChangeEvent Notice let highlightCenter: SWHighlightCenter = self.highlightCenter let highlight = try highlightCenter.collaborationHighlight(forURL: ckShareURL, error: &error) let editEvent = SWHighlightChangeEvent(highlight: highlight, trigger: .edit) highlightCenter.postNotice(for: editEvent)
-
21:30 - Post an SWHighlightMentionEvent Notice
// Post an SWHighlightMentionEvent Notice let highlightCenter: SWHighlightCenter = self.highlightCenter let highlight = try highlightCenter.collaborationHighlight(forURL: ckShareURL, error: &error) let mentionEvent = SWHighlightMentionEvent(highlight: highlight, mentionedPersonCloudKitShareHandle: ckShareParticipantHandle) highlightCenter.postNotice(for: mentionEvent)
-
21:58 - Post an SWHighlightPersistenceEvent Notice
// Post an SWHighlightPersistenceEvent Notice let highlightCenter: SWHighlightCenter = self.highlightCenter let highlight = try highlightCenter.collaborationHighlight(forURL: ckShareURL, error: &error) let renamedEvent = SWHighlightPersistenceEvent(highlight: highlight, trigger: .renamed) highlightCenter.postNotice(for: renamedEvent)
-
22:11 - Post an SWHighlightMembershipEvent Notice
// Post an SWHighlightMembershipEvent Notice let highlightCenter: SWHighlightCenter = self.highlightCenter let highlight = try highlightCenter.collaborationHighlight(forURL: ckShareURL, error: &error) let membershipEvent = SWHighlightMembershipEvent(highlight: highlight, trigger: .addedCollaborator) highlightCenter.postNotice(for: membershipEvent)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。