场景

  • 在自己的APP中自定义快捷指令
  • 通过 Siri 语音触发,可以跳转进入APP或者后台执行操作

主要过程:

  • 创建一个Intent 意图文件,里面配置自定的意图内容
  • 创建Intent Extension 拓展,代码处理识别到的意图回调
  • 主工程中的录入/编辑指令操作

Intent Xcode 中 配置

创建 Intent 意图文件

Xcode - File - New — File — 搜索Intent
image.png|500

增加 Intent 意图

选择 Intent 意图文件
image.png|500

  • New Intent 设置自定义意图
  • Customize System Intent 系统提供的意图

在这选择 New Intent

配置意图内容

image.png|500
配置后默认有内容:
自定义的意图是一个可配置的动态文件,配置完成后,重新编译会自动生成代码
比如现在配置的意图是:ControlScene,会自动生成 SHControlSceneIntent 类

Custom Intent
image.png|500

这边只要选择:Suggestions 选项就行,因为我们不是要通过快捷指令APP中配置,而是要在自己的APP中配置

增加参数配置

image.png|500

响应结果

image.png|500

创建Intent Extension

添加 Target - 搜索 Intents 找到 Intents Extesion 就行
image.png|500

image.png|500

如果不要自定义 UI ,UI Extension可以不用选择

下一步 选择 Activited ,创建成功

注意
要将上述创建的 意图文件关联到这个工程,编译后模板文件才会自动生成。

以上述 指令为例,编译后自动生成的文件内容
image.png|500
image.png|500

IntentHandler 类

这个是主要来处理指令回调的内容
image.png|500

处理流程步骤为
image.png|500

多语言

image.png|500

  • 选择多语言类型
  • 多语言的key是自动生成的

代码处理

在后台处理执行,不唤醒APP

1
2
3
4
5
6
7
8
9
10
- (void)handleControlScene:(nonnull SHControlSceneIntent *)intent completion:(nonnull void (^)(SHControlSceneIntentResponse * _Nonnull))completion {

/*
在后台进行业务处理,不唤醒APP
*/
// 处理成功结果弹窗
completion([[SHControlSceneIntentResponse alloc] initWithCode:SHControlSceneIntentResponseCodeSuccess userActivity:nil]);
// 处理失败结果弹窗
completion([[SHControlSceneIntentResponse alloc] initWithCode:SHControlSceneIntentResponseCodeFailure userActivity:nil]);
}

唤醒APP,处理指令

唤醒APP

1
2
3
4
- (void)handleControlScene:(nonnull SHControlSceneIntent *)intent completion:(nonnull void (^)(SHControlSceneIntentResponse * _Nonnull))completion {

completion([[SHControlSceneIntentResponse alloc] initWithCode:SHControlSceneIntentResponseCodeContinueInApp userActivity:nil]);
}

在APP工程中处理指令

1
2
3
4
5
6
7
8
9
10
11
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {

if([userActivity.interaction.intent isKindOfClass:[SHControlSceneIntent class]]){
SHControlSceneIntent *intent = (SHControlSceneIntent *)userActivity.interaction.intent;
NSLog(@"====== %@", intent.parameter);

// 处理业务

return YES;
}
}

主工程中的代码处理

我们需要处理的内容

  • 获取所有快捷指令
  • 新增快捷指令
  • 编辑快捷指令
  • 删除快捷指令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 主要的库
#import <Intents/Intents.h>
#import <IntentsUI/IntentsUI.h>

// 获取所有快捷指令
- (void)getAllShortCuts {
[[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {

}];
}

// 新增快捷指令
- (void)addShortcutInstruction:(NSString *)data {
if (@available(iOS 12.0, *)) {

SHControlSceneIntent *intent = [[SHControlSceneIntent alloc] init];
intent.parameter = data; // 指令携带的参数


INShortcut *shortcut = [[INShortcut alloc] initWithIntent:intent];

INUIAddVoiceShortcutViewController *addVoiceShortcutViewController = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortcut];
addVoiceShortcutViewController.delegate = self;
addVoiceShortcutViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:addVoiceShortcutViewController animated:YES completion:nil];
}
}

// 编辑/删除快捷指令
- (void)editVoiceShortcut:(INVoiceShortcut *)voiceShortcut {

INUIEditVoiceShortcutViewController *editVoiceShortcutViewController = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcut];
editVoiceShortcutViewController.delegate = self;
editVoiceShortcutViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:editVoiceShortcutViewController animated:YES completion:nil];
}

主工程配置

Capabilities 新增Siri
image.png|500

在info.plist 新增属性 ”Privacy - Siri Usage Description”

问题

Parameter voice-only prompt dialog can’t be empty

1
error: Scene.parameter: Parameter voice-only prompt dialog can’t be empty. Alternately, this parameter can be marked as unresolvable.

配置信息:
image.png|500

不能执行回调方法

Target 没有设置 最低版本
image.png|500

参考

SiriKit框架详细解析
制作可配置小组件
爱奇艺 iOS 深度实践:SiriKit 详解应用篇
Siri shortcuts 创建
Apple custom intent