iOS之快捷指令的集成
一、自己APP添加可由siri唤起的快捷指令
- 首先导入三个系统库
#import <Intents/Intents.h>
#import <IntentsUI/IntentsUI.h>
#import <CoreSpotlight/CoreSpotlight.h>
- 需要遵循两个协议并实现其对应的方法
INUIAddVoiceShortcutViewControllerDelegate
INUIEditVoiceShortcutViewControllerDelegate
这两个协议分别代表了新增shortcut时弹出的页面对应操作以及编辑已添加shortcut时弹出的页面对应的操作
其对应的协议方法为:
#pragma mark - INUIAddVoiceShortcutViewControllerDelegate
- (void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(nullable INVoiceShortcut *)voiceShortcut error:(nullable NSError *)error API_AVAILABLE(ios(12.0))
{
}
- (void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller API_AVAILABLE(ios(12.0))
{
}
#pragma mark- INUIEditVoiceShortcutViewControllerDelegate
- (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didUpdateVoiceShortcut:(nullable INVoiceShortcut *)voiceShortcut error:(nullable NSError *)error API_AVAILABLE(ios(12.0))
{
}
- (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didDeleteVoiceShortcutWithIdentifier:(NSUUID *)deletedVoiceShortcutIdentifier API_AVAILABLE(ios(12.0))
{
}
- (void)editVoiceShortcutViewControllerDidCancel:(INUIEditVoiceShortcutViewController *)controller
{
}
由于shortcut功能为iOS12以上才可以用的,因此在集成该功能时需要做系统版本判断
if (@available(iOS 12.0, *))
1.新增
在添加快捷指令之前,需要先遍历已经存在的指令集合,确认想要添加的指令并没有被添加,用以下方法可以获取到所以已添加的shortcut
[[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {}];
查看INVoiceShortcut
类文件有三个属性invocationPhrase
、shortcut
、identifier
前两个分别表示指令的命令文案
、捷径对象(INShortcut
类),该对象中拥有两个重要的属性intent
、userActivity
前者后面第二部分内容再讲,后者中的activityType
、title
属性分别代表我们进行辨别快捷指令的id以及可由用户编辑的命令文案
。
将想要添加的userActivity
在指令集合中遍历对应的voiceShortcut.shortcut.userActivity.activityType
所有都不相同,则可以配置新指令内容进行添加
if (!isExist)
{
NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:activityType];
userActivity.title = defaultCommand;
userActivity.eligibleForSearch = YES;
if (@available(iOS 12.0, *))
{
userActivity.eligibleForPrediction = YES;
userActivity.suggestedInvocationPhrase = editableCommand;
}
CSSearchableItemAttributeSet *attributes = [[CSSearchableItemAttributeSet alloc] init];
if (thumbnailData) attributes.thumbnailData = thumbnailData;
attributes.contentDescription = editableCommand;
userActivity.contentAttributeSet = attributes;
dispatch_async(dispatch_get_main_queue(), ^{
// UI更新代码
INShortcut *shortCuts = [[INShortcut alloc] initWithUserActivity:userActivity];
INUIAddVoiceShortcutViewController *addvc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortCuts];
addvc.delegate = self;
self.addShortcutCompletion = completion;
self.defaultTitle = [self defaultTitleOfActivityType:activityType];
[[UIViewController sy_TopViewController] presentViewController:addvc animated:YES completion:^{
NSLog(@"跳往设置语音界面!");
}];
});
}
2.编辑
编辑已存在的快捷指令时,同样需要先遍历一遍已存在指令集合,找到与指定userActivity
一致的那一项开始调起编辑页面
// 获取已注册的voiceShortcuts
[[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {
for (int i = 0; i < voiceShortcuts.count; i++)
{
INVoiceShortcut *voiceShortcut = voiceShortcuts[i];
self.lastTitle = voiceShortcut.invocationPhrase;
self.defaultTitle = [self defaultTitleOfActivityType:activityType];
if ([voiceShortcut.shortcut.userActivity.activityType isEqualToString:activityType])
{
[self jumpToSiriEditViewControllerWithVoiceShortcut:voiceShortcut];break;
}
else if (voiceShortcut.shortcut.intent && [activityType isEqualToString:NSStringFromClass([voiceShortcut.shortcut.intent class])])
{
[self jumpToSiriEditViewControllerWithVoiceShortcut:voiceShortcut];break;
}
}
}];
/// 跳转到编辑页面
- (void)jumpToSiriEditViewControllerWithVoiceShortcut:(INVoiceShortcut *)voiceShortcut
API_AVAILABLE(ios(12.0)){
dispatch_async(dispatch_get_main_queue(), ^{
INUIEditVoiceShortcutViewController *editVC = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcut];
editVC.delegate = self;
[[UIViewController sy_TopViewController] presentViewController:editVC animated:YES completion:^{
NSLog(@"跳往设置语音界面!");
}];
});
}
二、在快捷指令应用中添加绑定自己APP的快捷指令
该阶段的目的
: 使自己在应用代码中添加的快捷指令可以与快捷指令app中添加的命令一一对应起来,并且可以在快捷指令app新增指令时可选择app列表中显示自己的app
如何将自己的app放到快捷指令app的列表中呢?需要新增一个extension
操作步骤为File->Target->iOS->Intents Extension
点
Next
后添上extension
的名称并把UI Extension
选项取消勾选
,如果是多target项目
注意该extension关联的target别选错image.png
新建extension
完成后配置好Bundle identifier
,并在关联的target
中添加一个group
项,该group项需要在开发者账号中进行配置
,配置好后将对应的描述文件下载下来安装好就行了,注意:添加group时需要在xcode登录开发者账号
接下来需要新建一个意图文件
,步骤为: File->File->搜索siri
找到名为SiriKit Intent Definition File
的文件点击创建,名称随便取一般项目中只有一个
在意图文件中添加一条新的意图,选择
New Intent
image.png
起意图的名字修改意图的描述文案取消Intent is eligible for Siri Suggestions打钩
注意: 该意图的名字会在唤起的时候被喜欢加上Intent后缀作为activityType传入应用,例:意图名为SYSiriShortcutSearch, 则activityType为SYSiriShortcutSearchIntent
当做完这些之后,就可以在系统的快捷指令应用中找到自己的app了,并且添加的意图也可以在下一步功能列表中找到。
最后需要注意一点:
快捷指令应用中同一条指令可以添加多个功能项
,在唤起
该指令的时候会先后一个个的调起application:continueUserActivity:restorationHandler:
方法(配置了UniversalLink的情况)并传入userActivity.activityType
用以区分指令
图示如下:
IMG_5425.PNG IMG_5426.PNG IMG_5427.PNG