想要通过Siri Shortcuts 实现 App 内上一次操作 iOS 开发,核心是使用Siri Shortcuts的捐赠(Donation)机制,让Siri学习用户习惯并建议快捷指令。以下是具体的技术实现方案:
核心实现原理
Siri Shortcuts 允许App将用户的操作“捐赠”给系统,系统学习后会在锁屏、搜索等场景中建议该操作,用户可为其设置语音短语,实现语音触发。
具体实现步骤(基于NSUserActivity)
定义快捷指令类型
在App的Info.plist中添加NSUserActivityTypes数组,声明一个唯一的activity type,例如:com.yourcompany.yourapp.repeatLastAction。-
在用户执行操作时捐赠(Donate)Shortcut
当用户在App内执行一个你希望能被重复的操作(例如:测量心率)时,创建并捐赠一个NSUserActivity。// 示例代码(Swift) let userActivity = NSUserActivity(activityType: "com.yourcompany.yourapp.repeatLastAction") userActivity.title = "重复上次测量" // 显示给用户的标题 userActivity.isEligibleForSearch = true userActivity.isEligibleForPrediction = true // 关键:允许Siri预测和建议 // 将上一次操作的具体参数(如测量类型、设置)存入userInfo userActivity.userInfo = ["action": "measureHeartRate", "timestamp": Date().timeIntervalSince1970] userActivity.suggestedInvocationPhrase = "重复测量" // 建议的Siri语音指令 viewController.userActivity = userActivity userActivity.becomeCurrent() // 捐赠给系统 -
处理Siri触发的快捷指令
在AppDelegate中实现application:continueUserActivity:restorationHandler:方法,处理Siri发起的请求。func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool { if userActivity.activityType == "com.yourcompany.yourapp.repeatLastAction" { // 从userActivity.userInfo中解析出上一次操作的参数 // 执行重复上一次操作的逻辑(例如:再次调用心率测量函数) repeatLastMeasurement() return true } return false }
针对“上一次操作”的特殊处理
-
状态记录:App需要内部记录最近一次成功操作的类型和参数(例如,存入
UserDefaults或内存变量),以便在捐赠NSUserActivity时能将其存入userInfo。 -
参数传递:通过
userInfo传递必要参数,确保Siri触发时能准确还原操作。
注意事项
- 用户习惯学习:Siri需要多次捐赠(即用户多次执行该操作)后,才会在“Siri建议”中显示。
- 功能范围:确保该操作符合苹果对Siri Shortcuts的推荐场景:App的关键功能、用户有重复性行为、随时可执行。
- 测试:在Xcode的模拟器或真机中,前往设置 > 开发者 > Shortcuts Testing,打开相关选项,便于调试。
在用户完成一次测量后,即时捐赠一个包含操作信息的NSUserActivity。系统学习后,用户即可通过“嘿Siri,重复测量”来触发App再次执行上一次的测量操作。
备选方案:使用Intents Framework
如果“重复上一次操作”逻辑复杂,或需在不启动App的情况下执行,可考虑使用更强大的Intents Framework创建自定义Intent。但这需要配置Intent Definition File和可能创建Intents App Extension,实现更复杂。
总结下两种方案的区别:
1. 基于 NSUserActivity 的方式 → 需要启动App
-
原理:通过
NSUserActivity将“重复上次操作”捐赠给Siri。当用户通过Siri或锁屏建议触发此快捷指令时,系统会启动App,并调用AppDelegate中的application(_:continue:restorationHandler:)方法。 -
原因:
NSUserActivity本身是一种轻量级的App状态记录,其处理逻辑必须写在主App中,因此执行时需要启动App。 - 用户体验:手机会有启动App的动画,然后执行预设的操作(如自动开始测量心率)。
2. 基于 Intents + App Extension 的方式 → 可以不启动主App
- 原理:需要为App创建一个 “Intents App Extension” 目标。在这个扩展中编写执行“重复上次操作”的代码。
- 优势:当用户触发快捷指令时,系统会直接运行这个扩展,无需启动完整的主App界面,体验更快捷。
-
代价:实现更复杂,需要管理主App与扩展之间的数据共享(例如,通过
UserDefaults(suiteName:)或App Groups来传递“上一次操作”的具体参数)。
建议
比如App核心功能是心率测量,且“重复上次操作”逻辑可能较简单:
-
如果追求快速实现和稳定:继续使用
NSUserActivity方案。虽然会启动App,但开发简单,对于用户来说,多一个启动步骤通常可以接受。 -
如果追求极致体验和无感执行:考虑升级为
Intents方案。这需要学习并创建App Extension,并处理好数据同步,但能实现“不启动App”的后台执行。
简单来说:按当前的 NSUserActivity 路径走,答案是“需要启动App”。若想避免启动,需改用更复杂的 Intents App Extension 技术。