在快捷指令 App 中展示你的操作
Feature your actions in the Shortcuts app
2020年6月25日
一句话判断
Shortcuts App 在 iOS 14 中有了全面改版,如果你的 App 已经支持 SiriKit 或 Intents,做好参数配置和发现优化就能让你的操作被更多用户发现和使用。
这场 Session 讲了什么
iOS 14 对快捷指令(Shortcuts)App 进行了重大重新设计。新的 Shortcuts App 采用了更清晰的分类结构,会自动发现已安装 App 的所有可用操作。Session 重点讲解了开发者如何让自己的 Intent 操作在 Shortcuts App 中获得更好的展示效果,包括参数配置、动态选项、交互预览等。
Apple 详细介绍了如何通过 Intent Definition File 配置参数的显示方式、如何提供动态选项列表(比如让用户从服务器获取最新的播放列表)、如何设置参数之间的依赖关系(选了专辑后才显示歌曲选项),以及如何让你的操作出现在 Shortcuts 的推荐分类中。
值得深挖的点
参数依赖与动态选项
这是 Shortcuts 集成中最有技术深度的部分。当你的 Intent 有多个参数时,参数之间可能存在依赖关系。比如”选择歌单 -> 选择歌曲”,歌曲列表取决于用户选了哪个歌单。通过 INParameter 的依赖关系配置,Shortcuts App 会在用户选择了第一个参数后才去查询第二个参数的选项,体验上就像原生 App 一样流畅。
Shortcuts 自动发现机制
iOS 14 的 Shortcuts App 会扫描所有已安装 App 的 Intent Definition,自动展示所有可用的操作。你不需要做额外的注册工作。但你可以通过 INShortcut 的 suggestedInvocationPhrase 和系统分类来提高发现性。Apple 建议为每个操作提供清晰的中文名称和描述,因为用户会在 Shortcuts 的列表中直接看到这些文本。
代码片段
配置 Intent 参数的动态选项
场景:为音乐 App 的”播放歌单”操作提供动态歌单列表。
import Intents
class PlaylistIntentHandler: NSObject, PlayPlaylistIntentHandling {
// 提供歌单的动态选项列表
func providePlaylistOptionsCollection(
for intent: PlayPlaylistIntent,
with completion: @escaping (INObjectCollection<Playlist>, Error?) -> Void) {
// 从服务器获取用户的所有歌单
MusicService.fetchPlaylists { playlists in
let items = playlists.map { playlist in
Playlist(identifier: playlist.id,
display: playlist.name)
}
let collection = INObjectCollection(items: items)
completion(collection, nil)
}
}
func handle(intent: PlayPlaylistIntent,
completion: @escaping (PlayPlaylistIntentResponse) -> Void) {
guard let playlist = intent.playlist else {
completion(.failure(error: "未选择歌单"))
return
}
// 开始播放选中的歌单
MusicPlayer.shared.play(playlistId: playlist.identifier)
completion(.success(result: playlist))
}
}
设置参数之间的依赖关系
场景:歌单选择后动态更新歌曲选项。
class SongIntentHandler: NSObject, PlaySongIntentHandling {
// 声明参数依赖:歌曲选项依赖于歌单参数
static func playlistChoices(for intent: PlaySongIntent) -> [INParameter] {
// 告诉系统 playlist 参数的选择会影响 song 参数的选项
return [INParameter(parameters: \PlaySongIntent.playlist)]
}
// 提供歌曲的动态选项(依赖于已选择的歌单)
func provideSongOptionsCollection(
for intent: PlaySongIntent,
with completion: @escaping (INObjectCollection<Song>, Error?) -> Void) {
guard let playlistId = intent.playlist?.identifier else {
completion(INObjectCollection(items: []), nil)
return
}
// 根据选中的歌单获取歌曲列表
MusicService.fetchSongs(playlistId: playlistId) { songs in
let items = songs.map { song in
Song(identifier: song.id, display: song.title)
}
completion(INObjectCollection(items: items), nil)
}
}
}
创建 INShortcut 并设置建议短语
场景:为 Shortcuts App 创建可发现的快捷方式。
import Intents
// 从 Intent 创建 Shortcut
func createShortcuts() {
// 方法一:从 Intent 创建
var intent = PlayPlaylistIntent()
intent.playlist = Playlist(identifier: "favorites",
display: "我的收藏")
intent.suggestedInvocationPhrase = "播放我的收藏"
if let shortcut = INShortcut(intent: intent) {
// 捐赠给系统,让 Siri 学会推荐
let interaction = INInteraction(intent: intent, response: nil)
interaction.donate { error in
if let error = error {
print("捐赠快捷方式失败: \(error)")
}
}
}
// 方法二:从 NSUserActivity 创建
let activity = NSUserActivity(activityType: "com.yourapp.play")
activity.title = "播放音乐"
activity.isEligibleForSearch = true
activity.isEligibleForPrediction = true
activity.suggestedInvocationPhrase = "播放音乐"
activity.becomeCurrent()
}
最佳实践
已有项目:如果你的 App 已经支持 SiriKit,确保所有的 Intent 参数都配置了正确的 display name 和描述。检查 Intent Definition File 中的参数顺序——排在前面的参数会先被用户填写。为常用操作设置合理的 suggestedInvocationPhrase。
新项目:从产品角度规划哪些功能适合暴露为 Shortcuts 操作。优先选择”一个输入 -> 一个输出”的简单操作,比如”播放某歌单”、“发送消息给某人”。复杂的操作链用 Shortcuts 的 Workflow 功能组合即可。
还有什么值得关注
- Shortcuts 现在支持文件夹分类,你的操作可以通过 Intent Category 自动归入对应文件夹。
- iOS 14 新增了”快捷指令”桌面小组件,用户可以把常用操作放在主屏,这进一步放大了 Shortcuts 集成的价值。
- 动态选项支持分页加载,如果你的选项列表很长,使用
INObjectCollection的分页能力避免一次性加载过多数据。