WWDC Quick Look 💓 By SwiftGGTeam
Expand your SiriKit Media Intents to more platforms

Expand your SiriKit Media Intents to more platforms

观看原视频

Highlight

2020 年,SiriKit Media Intents 扩展到 HomePod 和 tvOS 14,并新增 alternatives UI、in-app intent handling 与 app prewarming,让媒体 App 能在 Siri 内给出备选结果并更快开始播放。


核心内容

做音乐、播客或有声内容 App 时,Siri 请求的难点通常不在于播放按钮。用户说的是自然语言,比如“播放某张专辑里的歌”,你的 App 要把这句话解析成一个真实的媒体项,再尽快开始播放。以前如果匹配错了,compact Siri UI 只能直接开始播放第一个结果,用户想换一首歌往往要打开 App。

这场 session 先把平台范围扩大。HomePod 使用相同的 Media Intents,并配合新的 cloud playback API 适应家庭场景。tvOS 14 也支持 SiriKit Media Intents,电视端 App 可以像 iOS App 一样处理 INPlayMediaIntent,让用户在大屏幕上直接用 Siri 点播内容。

第二个变化是 alternatives UI。App 可以一次返回多个候选媒体项。Siri 先播放第一个结果,同时把后续候选放在 “Maybe You Wanted” 菜单里。用户点选替代项后,Siri 会把这个媒体项放进传给 handleINPlayMediaIntent,开发者沿用原来的播放路径即可。

最后是启动性能。2020 年新增两条路径:in-app intent handling 把 resolve、confirm、handle 移到 App 进程里;app prewarming 则让使用 extension 的 App 更早启动,提前准备凭据和播放器。两者的目标相同:缩短用户说完请求到内容开始播放之间的等待。

详细内容

HomePod 和 tvOS 14 扩展

01:00

HomePod 使用同一套 media intents,并引入新的 cloud playback API。session 没有展示 HomePod 端代码,而是指向 developer.apple.com/siri 的开发者计划信息。可落地的结论是:如果你的服务要接入 HomePod,需要先确认媒体搜索、用户账号和云端播放链路能在没有本地 App UI 的场景下完成。

02:25

tvOS 的接入方式复用 iOS 里的 Intent extension 思路。核心入口仍然是 resolveMediaItems,它接收 INPlayMediaIntent,从自然语言请求中找到具体媒体项。

func resolveMediaItems(for intent: INPlayMediaIntent, with completion: @escaping ([INPlayMediaMediaItemResolutionResult]) -> Void) {
}

关键点:

  • INPlayMediaIntent 是 Siri 解析后的播放请求。
  • resolveMediaItems 负责把请求转成 App 内部可播放的媒体项。
  • completion 返回的是 resolution results,后续 Siri 会根据这些结果继续进入 handle 阶段。

03:03

tvOS 上用户通常一次只和一个前台 App 交互,所以 session 建议在 handle 里返回 .continueInApp,让 App 以前台方式启动并开始播放。

func handle(intent: INPlayMediaIntent, completion: (INPlayMediaIntentResponse) -> Void) {
  completion(INPlayMediaIntentResponse(code: .continueInApp, userActivity: nil))
}

关键点:

  • handle 是真正开始播放前的响应阶段。
  • .continueInApp 告诉系统继续进入 App,而不是只在后台处理。
  • userActivity 这里传入 nil,因为示例只演示播放路径切换。

Alternatives UI

05:24

旧做法只返回一个媒体项。Siri 只能播放这个结果。

INPlayMediaMediaItemResolutionResult.success(with: mediaItems[0])

关键点:

  • success(with:) 是单数 API。
  • 返回值只有一个 resolved media item。
  • compact Siri UI 没有足够信息展示备选项。

05:40

2020 年新增的复数 API 可以返回多个媒体项。第一个项目会被播放,后面的项目显示为 alternatives。

INPlayMediaMediaItemResolutionResult.successes(with: mediaItems)

关键点:

  • successes(with:) 接收媒体项数组。
  • 数组第一个元素仍然是默认播放结果。
  • 后续元素进入 Siri 的 “Maybe You Wanted” 替代结果界面。

06:37

示例 App ControlAudio 的改动集中在 resolveMediaItems。它先从 intent 取出 mediaSearch,再把搜索结果一次性交给复数 resolution API。

func resolveMediaItems(for intent: INPlayMediaIntent, with completion: @escaping ([INPlayMediaMediaItemResolutionResult]) -> Void) {
    let mediaSearch = intent.mediaSearch
    resolveMediaItems(for: mediaSearch) { optionalMediaItems in
        guard let mediaItems = optionalMediaItems else {
            return
        }
        completion(INPlayMediaMediaItemResolutionResult.successes(with: mediaItems))
    }
}

关键点:

  • intent.mediaSearch 是 Siri 对用户请求的结构化媒体搜索条件。
  • 内层 resolveMediaItems(for: mediaSearch) 代表 App 自己的搜索逻辑。
  • guard let mediaItems 避免在没有搜索结果时提交空数据。
  • successes(with:) 是触发 alternatives UI 的关键变化。

06:07

用户点选某个替代项后,不需要新的回调模型。Siri 会把被点选的媒体项设置进传给 handleINPlayMediaIntent,App 继续按现有播放逻辑处理。

func handle(intent: INPlayMediaIntent, completion: (INPlayMediaIntentResponse) -> Void) {
  completion(INPlayMediaIntentResponse(code: .handleInApp, userActivity: nil))
}

关键点:

  • 替代项选择后的入口仍然是 handle
  • .handleInApp 表示让 App 在自身进程内处理播放。
  • 代码不需要区分“首次命中”和“用户选择替代项”两套流程。

In-app intent handling 和 app prewarming

08:28

in-app intent handling 把 intent handling stages 移进 App,而不是先启动 Intents extension 再启动 App。这样可以少启动一个进程,也能在 resolve 阶段更早发起网络请求、获取凭据或准备播放器。

session 同时提醒:完整 App 比 extension 更重。如果采用 in-app intent handling,需要优化 App 启动路径,保证 resolve 阶段的 Siri 响应速度。

10:24

如果继续使用 extension,app prewarming 可以让 App 更早启动。预热逻辑应放在 application(_:didFinishLaunchingWithOptions:) 里,例如准备凭据或播放器。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Locate any app prewarming logic in this method -- fetch credentials, get audio player ready, etc.
    return true
}

关键点:

  • 预热发生在 App 启动入口。
  • session 给出的例子是获取 credentials 和准备 audio player。
  • 这条路径适合已有 extension 架构的 App,因为 intent 解析逻辑仍可留在 extension 中。

核心启发

电视端语音点播入口

  • 做什么:给 tvOS 音乐、播客或视频 App 增加 Siri 播放入口,让用户在电视上直接说出内容名称、乐队或歌曲。
  • 为什么值得做:tvOS 14 支持 SiriKit Media Intents,session 明确说 tvOS 接入步骤与 iOS 相同。
  • 怎么开始:复用现有 INPlayMediaIntent 解析逻辑,在 tvOS target 中补齐 Intent extension,并在 handle 中返回 .continueInApp

搜索结果替代菜单

  • 做什么:当用户请求可能匹配多首歌、多个播客单集或同名专辑时,在 Siri 中展示候选项。
  • 为什么值得做:alternatives UI 允许用户在 compact Siri UI 里换结果,减少打开 App 的次数。
  • 怎么开始:把单数 success(with:) 改成复数 successes(with:),把最可能的媒体项放在数组第一位。

播放前预热链路

  • 做什么:在 Siri 请求进入播放前提前获取用户凭据、初始化播放器或准备音频会话。
  • 为什么值得做:session 把 credential fetching 和 audio player setup 作为 app prewarming 的典型场景。
  • 怎么开始:如果继续使用 extension,把轻量预热放入 application(_:didFinishLaunchingWithOptions:);如果改用 in-app intent handling,把必要请求提前到 resolve 阶段。

HomePod 接入评估

  • 做什么:为音频服务整理 HomePod 接入清单,确认账号、媒体搜索和云端播放路径是否能脱离本地 UI 工作。
  • 为什么值得做:HomePod 使用相同的 media intents,并通过 cloud playback API 适配家庭播放场景。
  • 怎么开始:先阅读 session Resources 中的 HomePod 接入申请链接和 SiriKit 音频管理文档,再用现有媒体搜索逻辑验证 Siri 请求能否稳定返回唯一或多个候选项。

关联 Session

评论

GitHub Issues · utterances