在 iOS12 系统推出,Apple 同时也发布了一个新的 App —— shortcuts。与以往不同的是该 App 不是直接集成在系统的中,而是在 App Store 中提供下载。shortcuts 翻译成 捷径。在 iOS9 就已经有 shortcut 的概念了,在 AppIcon 使用 3DTouch 就会出现一些 shortcutsItem 如果该 App 有集成的话(至少会有一个分享的 item),所以 shortcuts 是为了让复杂的操作简单化的一个工具。那么我们如何在 App 中集成 shortcuts,或者说怎么在捷径 App 中使用我们的相关的功能呢?有两种方式能达到我们的目的: NSUserActivity 和 Intents

NSUserActivity

  1. 在 info.plist 中添加 NSUserActivityTypes 字段

    在 info.plist 中添加 NSUserActivityTypes 字段,并将设置唯一的 id 作为后面时候的 NSUserActivity 的 activityType。

  2. 在某一个 ViewController 中或者 UIResponse 子类中添加 userActivity

    创建一个 userActivity 对象,设置 title 和一些能否被 spotlight 搜索、是否支持 handoff 等等,然后通过 becomeCurrent 方法或者对 UIRepsonse 子类的中的 userActivity 赋值,将其注册到 shortcuts 中。

1
2
3
4
5
6
7
8
9
10
11
12
let userActivity = NSUserActivity(activityType: "com.aaa.bbb.userActivity")
if #available(iOS 9.0, *) {
userActivity.isEligibleForSearch = true
userActivity.isEligibleForHandoff = true
}
if #available(iOS 12, *) {
userActivity.isEligibleForPrediction = true
userActivity.suggestedInvocationPhrase = "每日排行榜"
}
userActivity.title = "xxx-每日排行榜"
//userActivity.becomeCurrent() 效果和 self.userActivity = userActivity 一样
self.userActivity = userActivity
  1. 在 AppDelegate 的回调方法内处理

    在该代理方法中对 userActivity 的 activityType 判断作出相应的处理

1
2
3
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

}

Intent

  1. 新建 SiriKit intent

    新建一个 SiriKit Intent Definition File ,在 iOS12 中我们不能够自定义一个 Intent,而是这样的一个 Definition File,它类似一个模版。在编译阶段会生成对应的 Intent 类。

以下是对应一个 intentdefinition 文件的内容,它可以包含多个 custom intent 和 system Intent。

我们可以看到一个 Intent 分为三个模块:Custom Intent、Parameters 和 Shortcut Types。

  1. Custom Intent

    • Category 是 Intent 类别,它是系统为了提供了一些对 Intent 的分类。

    • Title 是标题,Intent 在 Shortcuts App 中显示的名称

    • Description 描述你的 Intent

    • Default Image 是一个 shortcuts 的 icon

  2. Parameters,在这个模块中定义参数,在生成的 xxxIntent 类中也会生成对应的属性。这些属性可以在下一个模块 Shortcut Types 中是使用,填充相应的 Title 和 subTitle

  3. Shortcut Types 通过对参数的组合可以生成想要的模版

Intent 还有 response 一项,也是和以上的类似,根据成功和失败给出相应的模版文案。

  1. 添加到 shortcuts

实例化一个自定义的 Intent,设置相关的属性。每一个 Intent 对应一个 INInteraction 然后调用 donate 方法,将这个 Intent “注册“ 到 Shortcuts。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
let intent = PasteSearchIntent()
intent.hint = "输入你要搜索的词语(String)"
intent.searchWord = "搜索词"
registerIntent([intent, INSendMessageIntent()])

func registerIntent(_ intents: [INIntent]) {
intents.forEach { intent in
let interaction = INInteraction(intent: intent, response: nil)
interaction.donate { error in
if let error = error {
print("error = \(error)")
return
}
}
}
}
运行 App,在 Shortcut App 内就可以看到我们注册的 Intent。
  1. 处理相应的 Intent

    用以下代理方法处理相应的 Intent 。

1
2
3
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {

}

总结

Shortcuts App 是 Apple 对 workflow 的一个替代品,对用户更加友好。目前第三方 App 需要集成 shortcut,还不支持输入参数,我们看到有些 App 可以添加用户输入,像 招商银行 等,经过测试发现系统提供的部分 Intent 是支持用户输入的,可以在 Definition File 新建一个 System Intent。 不使用 System Intent ,还是有些办法可以达到这样的效果的,就是通过 URL Scheme 的方式传递参数。从产品的角度,App 中使用频繁、重复率高的功能可以作为集成 shortcut 的切入点,在用户第一次使用完这个功能之后,可以询问用户是否添加到 shortcut 以便之后高效使用。

参考

Shortcuts: A New Vision for Siri and iOS Automation

iOS12 Siri Shortcuts详解

SiriKit