如果你想要在Siri界面直接进行一些操作,而不是让Siri打开APP。那么你可能需要使用Intent Extension
了。先看下效果:
1.添加Intents文件
File -> New File
,选择SiriKit Intent Definition File
2.配置Instents文件
3.配置参数
这里的Category
是对应Siri
界面唤醒Extentsion
的不同样式的。上面那个需要确认的就是Order
,直接运行的就是Generic
创建完成后,编译一下项目,Xcode 会自动生成对应的类,我这里的话会生成 SceneIntent
,每个类包含了 SceneIntentHandling
协议和 SceneIntentResponse
类等所需要的内容。
需要注意的是,这些类不会出现在项目的目录中,有点和 Core Data 类似。
但你可以正常使用,可以为其新建 Category 或者导入头文件就可以直接使用。
Intents Extension
接下来就是创建 Extension
了。通过file -> new -> target
, 选择Intents Extension
即可。为了让 Extension
的界面便于控制,我选择了 Include UI Extension
。这样就同时创建了两个Extension
。
Intents Extension
创建好后,会自动出现一个名为 IntentHandler
的类。对于非即时通讯类的需求,可以删除其他的方法,保留下面一个方法即可:
- (id)handlerForIntent:(INIntent *)intent;
handlerForIntent
方法是整个 Intents Extension
的入口,当 Siri 通过语音指令匹配到对于的 Intent
, 该方法就会被执行。这里我 return 我创建一个 SceneIntentHandler
类,该类准守SceneIntentHandling
协议。 用来处理匹配到 Intent
后的 UI 显示以及后续操作。
该协议有两个方法:
该方法是在Siri
匹配到相应的 Intent
时候调用。
通过 completion
返回一个 SceneIntentResponse
。
- (void)confirmSendMessage:(INSendMessageIntent *)intent completion:(void (^)(INSendMessageIntentResponse *response))completion
而下面这个方法是用户对 Intent UI
的操作回调,比如用户点击了图一的“是”这个按钮, 或者是直接执行类的Category
- (void)handleScene:(LHSceneIntent *)intent completion:(void (^)(LHSceneIntentResponse * _Nonnull))completion
请求成功,传递 SceneIntentResponseCodeSuccess
状态。
请求失败,传递之前自定义的 SceneIntentResponseCodeFailureWithSomething
状态,并且附带上 errorMessage
信息。供后面的 IntentUI
使用。
PS: 这两个方法不一定都要实现,但是如果实现一定要返回一个completion回调出去,不然Siri会报错,出现下面的情况:
Intents Extension UI
最后就是我们的 Intent UI
登场了。打开文件夹目录,会发现系统自动创建了一个名为IntentViewController
的类。
该类只有一个方法,很长的方法:
- (void)configureViewForParameters:(NSSet <INParameter *> *)parameters ofInteraction:(INInteraction *)interaction interactiveBehavior:(INUIInteractiveBehavior)interactiveBehavior context:(INUIHostedViewContext)context completion:(void (^)(BOOL success, NSSet <INParameter *> *configuredParameters, CGSize desiredSize))completion;
在这里我们处理不同的回调状态就可以了。
以上就是Siri Shortcut开发的大体流程了。
参考:
WWDC 2018 Shorcuts
iOS12 Siri ShortCuts 应用
苹果官方 Siri ShortCuts Demo