iOS之快捷指令的集成

2021-06-18  本文已影响0人  Bleiler

一、自己APP添加可由siri唤起的快捷指令

#import <Intents/Intents.h>
#import <IntentsUI/IntentsUI.h>
#import <CoreSpotlight/CoreSpotlight.h>
#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类文件有三个属性invocationPhraseshortcutidentifier前两个分别表示指令的命令文案、捷径对象(INShortcut类),该对象中拥有两个重要的属性intentuserActivity前者后面第二部分内容再讲,后者中的activityTypetitle属性分别代表我们进行辨别快捷指令的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

siriExtension.png
Next后添上extension的名称并把UI Extension选项取消勾选,如果是多target项目注意该extension关联的target别选错
image.png
新建extension完成后配置好Bundle identifier,并在关联的target中添加一个group项,该group项需要在开发者账号中进行配置,配置好后将对应的描述文件下载下来安装好就行了,注意:添加group时需要在xcode登录开发者账号

接下来需要新建一个意图文件,步骤为: File->File->搜索siri找到名为SiriKit Intent Definition File的文件点击创建,名称随便取一般项目中只有一个

image.png
在意图文件中添加一条新的意图,选择New Intent
image.png

起意图的名字修改意图的描述文案取消Intent is eligible for Siri Suggestions打钩

image.png

注意: 该意图的名字会在唤起的时候被喜欢加上Intent后缀作为activityType传入应用,例:意图名为SYSiriShortcutSearch, 则activityType为SYSiriShortcutSearchIntent

当做完这些之后,就可以在系统的快捷指令应用中找到自己的app了,并且添加的意图也可以在下一步功能列表中找到。

最后需要注意一点: 快捷指令应用中同一条指令可以添加多个功能项,在唤起该指令的时候会先后一个个的调起application:continueUserActivity:restorationHandler:方法(配置了UniversalLink的情况)并传入userActivity.activityType用以区分指令

图示如下:

IMG_5425.PNG IMG_5426.PNG IMG_5427.PNG
上一篇下一篇

猜你喜欢

热点阅读