Highlight
Shared with You 是 iOS 15 引入、iOS 16 开放给第三方开发者的功能。它的核心理念是:朋友在 Messages 里发给你的内容,不应该沉没在聊天记录里,而应该在你打开相关 App 时自动浮现。
核心内容
朋友在 Messages 里发来一部剧、一篇文章或一首歌时,用户常常不在消费内容的场景里。演讲举的例子是:朋友推荐电视节目时,你正在超市买东西;等打开 TV app 想看节目时,那条消息已经被新的聊天淹没(00:46)。
Shared with You 解决的是这个断点。内容仍然从 Messages 分享出去,但当用户进入真正消费内容的 App,系统可以把这些链接重新浮现出来。iOS 15 先让 Safari、News、Music、Podcasts、TV app 和 Photos 接入;iOS 16 把 Shared with You 扩展到第三方 App、链接和内容(01:51)。
接入体验由两块组成。Shared with You shelf 放在 App 的浏览页面,展示 Messages 里分享过的内容;Shared with You attribution view 放在内容卡片或详情页,显示谁分享了它,并允许用户直接回到对应的 Messages 对话(02:16)。
底层依赖 Universal Links。系统通过 App 与网站的双向关联判断链接属于哪个 App;用户不需要提前授权,置顶链接本身就是把内容显示到 Shared with You 的隐式许可。开启自动分享后,同一 App 的后续内容也能自动进入列表(05:59)。
详细内容
先用 Universal Links 建立内容归属
(09:27)接入顺序很明确:先支持 Universal Links,再在 Xcode 的 Capabilities 里添加 Shared with You Capability,最后在 App 中使用 Shared with You framework。
Universal Links 要求 App 和网站建立双向关联:App 添加 Associated Domains entitlement,网站提供 JSON 文件,声明哪些 URL 由 App 处理。用户点击共享链接时,系统会把 universal link 作为 user activity 交给 App delegate 处理(09:51)。
// 概念示例:Universal Links 的接入点
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else {
return false
}
// 根据 url 导航到 App 内对应内容
return openContent(for: url)
}
关键点:
NSUserActivityTypeBrowsingWeb:表示这次唤起来自 universal link。userActivity.webpageURL:Shared with You 后续传给 App 的内容 URL 也建立在同一套链接归属机制上。openContent(for:):这里是 App 自己的路由逻辑,负责把 URL 映射到内容详情页。- 这段是概念示例;演讲没有给出完整 App delegate 代码,只说明要响应系统提供的 user activity。
枚举 Shared with You shelf 的内容
(10:42)iOS 16 新增 Shared with You framework,核心类有三个:SWHighlightCenter、SWHighlight、SWAttributionView。SWHighlightCenter 负责取得当前 App 的 Shared with You 内容;SWHighlight 包装一个被分享的内容 URL;SWAttributionView 负责显示分享者信息并连接回 Messages 对话。
// Enumerate Shared with You shelf
class SharedWithYouViewController: UIViewController, SWHighlightCenterDelegate {
let highlightCenter = SWHighlightCenter()
override func viewDidLoad() {
super.viewDidLoad()
highlightCenter.delegate = self
}
func highlightCenterHighlightsDidChange(_ highlightCenter: SWHighlightCenter) {
for highlight in highlightCenter.highlights {
let highlightURL = highlight.url
// Generate a rich preview for the Highlight
}
}
}
关键点:
SWHighlightCenter():创建读取 Shared with You 内容的入口对象。highlightCenter.delegate = self:让当前控制器接收内容新增、删除或更新通知。highlightCenterHighlightsDidChange:Shared with You 列表变化时调用。highlightCenter.highlights:返回SWHighlight数组,App 可以保留旧数组并和新数组做 diff。highlight.url:取出被 Messages 分享的内容 URL,用它生成 shelf 中的缩略图、标题和副标题。
在内容上显示 attribution view
(13:01)Attribution view 是系统绘制的独立视图,显示分享者的姓名和头像,也会显示内容是否在 Messages 中被置顶。Apple 强调它是 out of process rendering:App 只拿到内容和视图,不能访问 Messages 收件人或具体对话(08:47)。
// Setting appearance of Attribution View
let attributionView = SWAttributionView()
attributionView.highlight = self.highlightCenter.highlights[index]
attributionView.preferredMaxLayoutWidth = maximumWidthForView
关键点:
SWAttributionView():创建显示分享来源的系统视图。attributionView.highlight:把某个SWHighlight绑定到 attribution view;设置后会触发系统渲染分享者信息。preferredMaxLayoutWidth:告诉视图最大可用宽度,视图会在这个空间内填充或适配。- 演讲提醒要给 attribution view 留出足够的垂直空间;高度会随 Dynamic Type 字号变化(14:18)。
控制对齐和显示场景
(14:36)Attribution view 可以在最大宽度内设置水平对齐。演讲展示了 leading,同时说明还可以设为 center 或 trailing。
// Horizontal Alignment for Attribution View
let attributionView = SWAttributionView()
attributionView.highlight = self.highlightCenter.highlights[index]
attributionView.preferredMaxLayoutWidth = maximumWidthForView
attributionView.horizontalAlignment = .leading
关键点:
horizontalAlignment:控制 attribution view 内容在最大宽度内的位置。.leading:适合卡片底部这类从左侧开始阅读的布局。preferredMaxLayoutWidth与horizontalAlignment配合使用;前者定义可用空间,后者定义空间内的位置。
(14:51)displayContext 告诉系统用户正在怎样消费内容。默认值是 summary,表示内容处于摘要或浏览状态;用户正在看电影、听播客这类场景,应设置为 detail。这个反馈会影响 Siri Suggestions 对 Shared with You 内容的排序。
// Display Context for Attribution View
let attributionView = SWAttributionView()
attributionView.highlight = self.highlightCenter.highlights[index]
attributionView.preferredMaxLayoutWidth = maximumWidthForView
attributionView.horizontalAlignment = .center
attributionView.displayContext = .summary
关键点:
displayContext = .summary:表示内容以浏览摘要形式展示。displayContext = .detail:适合用户正在实际消费内容的详情场景;演讲用看电影和听播客举例。- 这个属性要在视图加入 window 之前设置。
- 系统还允许按背景选择 attribution view 的背景样式:单色背景可用 color,多色背景可用 material blur(15:47)。
把 Shared with You 菜单接到内容菜单里
(16:21)Attribution view 自带上下文菜单,例如 Reply 和 Remove。用户点 Reply 或直接点 attribution view,都可以进入对应 Messages 对话;Remove 用来告诉 Shared with You 以后不要再展示这条内容。
App 也可以把 attribution view 的菜单项追加到自己的内容菜单中。Remove 的标题可以自定义,但字符串需要包含本地化后的 “Remove”。Safari 的例子是 “Remove Link”(16:48)。
// Add Shared with You Content Menu to your app’s content
let attributionView = SWAttributionView()
attributionView.highlight = self.highlightCenter.highlights[index]
attributionView.menuTitleForHideAction = "Remove Item"
let contextMenuConfig = UIContextMenuConfiguration(identifier: nil,previewProvider: nil) { [weak self] _ in
let additionalMenu = attributionView.supplementalMenu
// Append additionalMenu items to your content’s menu items
}
关键点:
menuTitleForHideAction:自定义 Remove 菜单项标题,适合写成 “Remove Link” 或 “Remove Item” 这类对象明确的文案。UIContextMenuConfiguration:配置内容自身的上下文菜单。attributionView.supplementalMenu:取得 Shared with You 提供的附加菜单。Append additionalMenu:把系统菜单项追加到内容菜单的 inline 位置或末尾,保持用户在内容上长按时也能回复或移除。
核心启发
-
做一个内容推荐回收站:在视频、播客、文章 App 的首页加入 Shared with You shelf,把用户尚未消费的 Messages 链接重新展示出来。入口是
SWHighlightCenter.highlights,用highlight.url生成内容卡片。 -
给详情页加“谁推荐的”入口:在电影、音乐、食谱或商品详情页放置
SWAttributionView,让用户看到分享来源,并能直接回到 Messages 回复。入口是SWAttributionView.highlight和 attribution view 的点击交互。 -
用 display context 改善排序反馈:浏览页使用
.summary,播放页或阅读页使用.detail,让系统知道用户是否正在消费内容。入口是attributionView.displayContext,设置时机是在视图加入 window 之前。 -
统一内容长按菜单:把 Shared with You 的 Reply/Remove 菜单追加到 App 原有的卡片菜单里。入口是
attributionView.supplementalMenu和menuTitleForHideAction。 -
优先修好 Universal Links 诊断:Shared with You 依赖 Universal Links 识别内容归属。可以先写一个内部检查页,验证 Associated Domains entitlement、网站 JSON 文件和 App 内 URL 路由是否完整,再接入 shelf 和 attribution view。
关联 Session
- Integrate your custom collaboration app with Messages — 同样使用 SharedWithYou 框架,讲自定义协作 App 如何把分享、权限和通知接入 Messages。
- Enhance collaboration experiences with Messages — 讲 Messages 中的协作体验,适合和 Shared with You 的消息回流能力一起理解。
- What’s new in App Clips — App Clips 也依赖 Universal Links,演讲中的诊断工具能帮助排查链接配置问题。
- What’s new in Universal Links — Shared with You 建立在 Universal Links 上,这场 session 适合补齐链接关联和路由基础。
评论
GitHub Issues · utterances