介绍
升级iOS12之后可以在设置-Siri与搜索 中发现一个 捷径 功能, 所谓ShortCut就是其英文翻译
其作用就是让用户自定义一个一句话或者短语, 然后可以触发app做一系列动作
接入
ShortCut分为两种, 一种是在手机的Spotlight上搜索某个关键字的时候可以搜索到你的app, 这个关键字就是ShortCut的一种(文字输入), 你需要使用NSUserActivity去实现这个功能
依赖
CoreSpotlightCoreServices
另外一种叫做 Intent(语音输入), 需要添加一个IntentExtension和IntentExtensionUI, 然后在主Target添加一个intentdefinition文件, 详细的配置大家可以参考
文章1
文章2
依赖
IntentsIntentsUI
最简单的配置操作步骤
项目的
Capabilities打开Siri授权
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20if (@available(iOS 10.0, *)) {
[INPreferences requestSiriAuthorization:^(INSiriAuthorizationStatus status) {
switch (status) {
case INSiriAuthorizationStatusNotDetermined:
NSLog(@"用户尚未对该应用程序作出选择。");
break;
case INSiriAuthorizationStatusRestricted:
NSLog(@"此应用程序无权使用Siri服务");
break;
case INSiriAuthorizationStatusDenied:
NSLog(@"用户已明确拒绝此应用程序的授权");
break;
case INSiriAuthorizationStatusAuthorized:
NSLog(@"用户可以使用此应用程序的授权");
break;
default:
break;
}
}];
}- 新建一个
intentdefinition,比如A.intentdefinition - 新建一个
Target,Intent Extension有需要的话把Intent UI Extension也加上,General中配置相关证书 - 进入
A.intentdefinition,界面左下角+号点一下,点击new intent - 界面右边
Target Membership,把步骤2中新增的Target给勾上 - 界面中间
Title填写需要展示的标题,Descripion写描述 - Build一下,系统自动生成头文件,头文件名字在界面右测的导航页的第三个按钮的
Custom Class里 - 找个控制器,导入
步骤8生成的头文件,添加个按钮,比如
1
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"捷径" style:UIBarButtonItemStylePlain target:self action:@selector(siri:)];
- 新建一个
点击按钮召唤添加Shortcut的控制器
1
2
3
4
5
6
7
8
9
10
11
12
13- (void)siri:(UIBarButtonItem *)item {
if (@available(iOS 12.0, *)) {
// 这个类名具体看你生成了叫什么名字的头文件
ZeRiIntent *intent = [[ZeRiIntent alloc] init];
intent.suggestedInvocationPhrase = @"打开xxx"; // 引导用户说的语句
INShortcut *shortCur = [[INShortcut alloc] initWithIntent:intent];
INUIAddVoiceShortcutViewController *vc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortCur];
vc.delegate = self;
[self presentViewController:vc animated:YES completion:nil];
} else {
// Fallback on earlier versions
}
}同个地方实现代理方法
1
2
3
4
5
6
7#pragma mark - INUIAddVoiceShortcutViewControllerDelegate
- (void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller API_AVAILABLE(ios(12.0)){
[controller dismissViewControllerAnimated:YES completion:nil];
}
- (void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(INVoiceShortcut *)voiceShortcut error:(NSError *)error API_AVAILABLE(ios(12.0)){
[controller dismissViewControllerAnimated:YES completion:nil];
}进入
Intenttarget中的IntentHandler类,导入步骤8生成的头文件,要是头文件找不到,在这个target的info.plist中NSExtension下的IntentsSupported下添加一个名为那个头文件的值,主target的info.plist的NSUserActivityTypes下也加一个一样的IntentHandler.m遵循协议XXXIntentHandling(具体协议名看你的类名),实现两个方法1
2
3
4
5
6
7
8// 用户说了那句话之后要Siri做什么事情
- (void)handleZeRiIntent:(ZeRiIntent *)intent completion:(void (^)(ZeRiIntentResponse * _Nonnull))completion {
completion([[ZeRiIntentResponse alloc] initWithCode:ZeRiIntentResponseCodeContinueInApp userActivity:nil]);
}
// 用户确认了之后要Siri做什么事情
- (void)confirmZeRiIntent:(ZeRiIntent *)intent completion:(void (^)(ZeRiIntentResponse * _Nonnull))completion {
completion([[ZeRiIntentResponse alloc] initWithCode:ZeRiIntentResponseCodeContinueInApp userActivity:nil]);
}ZeRiIntentResponseCodeContinueInApp只是枚举中其中一个值,使用不同的值会有不同 效果,自己探索一下,这里的值指的是打开app(具体方法名看协议)进入
AppDelegate,实现方法如下,根据Intent类名判断用户想要的操作1
2
3
4
5- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
if ([userActivity.activityType isEqualToString:@"XXXIntent"]) {
}
return YES;
}结束