iOS12 Shortcuts

作者: 赵小超超 | 来源:发表于2018-09-26 23:24 被阅读324次

    简单些了一下,有不足往谅解。

    demo

    什么是shortcut?

    简单说就是往Sir里添加一条语音指令,通过Siri呼出指令后,打开对应的app,并跳转到指定页面。

    如何集成

    • 头文件依赖

    #import <CoreSpotlight/CoreSpotlight.h>
    #import <IntentsUI/IntentsUI.h>
    #import <Intents/Intents.h> //其中包含了#import <CoreSpotlight/CoreSpotlight.h>
    
    • 由于shortcut是iOS12才出现的,所有的操作都应该符号系统要求

        if (@available(iOS 12.0, *)) {
            NSString *invocationPhrase = @"哈哈哈";
            [self isInvocationPhraseExist:invocationPhrase block:^(BOOL exist, INVoiceShortcut *voiceShortcut) {
                [self donateShortCutsWithInvocationPhrase:invocationPhrase exist:exist voiceShortcut:voiceShortcut];
            }];
        }
    
    • 添加新的shortcut之前要先判断指令是否已经添加过

      查询操作是在子线程中执行的,拿到查询结果之后要返回主线程
    /**
     判断捷径是否已经存在
     */
    - (void)isInvocationPhraseExist:(NSString *)invocationPhrase block:(void (^)(BOOL exist, INVoiceShortcut *voiceShortcut))block API_AVAILABLE(ios(12.0)){
        NSLog(@"currentThread:%@", [NSThread currentThread]);//主线程
        //获取该app已经添加过的捷径,避免重复添加
        [[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {
            if (!error) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    BOOL exist = NO;
                    INVoiceShortcut *voiceShortcut = nil;
                    for (INVoiceShortcut *shortcut in voiceShortcuts) {
                        if ([shortcut.invocationPhrase isEqualToString:invocationPhrase]) {
                            exist = YES;
                            voiceShortcut = shortcut;
                            break;
                        } else {
                            exist = NO;
                        }
                    }
                    block(exist, voiceShortcut);
                });
            }
        }];
    }
    
    • 创建或者修改shortcut

    指令不存在则添加,存在则修改

    /**
     创建或者修改语音捷径
    
     @param invocationPhrase 提示的语音输入语句
     @param exist 是否已经存在
     @param voiceShortcut 已经存在的语音语句
     */
    - (void)donateShortCutsWithInvocationPhrase:(NSString *)invocationPhrase exist:(BOOL)exist voiceShortcut:(INVoiceShortcut *)voiceShortcut  API_AVAILABLE(ios(12.0)){
        NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:@"com.cc.siri"];
        activity.eligibleForSearch = YES;
        activity.title = @"我是title";
        activity.eligibleForPrediction = YES;
        activity.suggestedInvocationPhrase = invocationPhrase;
    
        CSSearchableItemAttributeSet *set = [[CSSearchableItemAttributeSet alloc] init];
        set.thumbnailData = UIImagePNGRepresentation([UIImage imageNamed:@"icon"]);
        set.contentDescription = @"我是描述";
    
        activity.contentAttributeSet = set;
    
        INShortcut *shortCut = [[INShortcut alloc] initWithUserActivity:activity];
        if (!exist) { //添加
            INUIAddVoiceShortcutViewController *shortCutVc = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortCut];
            shortCutVc.delegate = self;
            [self presentViewController:shortCutVc animated:YES completion:nil];
        } else { //修改 此处需要用已经存在的voiceShortcut来初始化控制器
            INUIEditVoiceShortcutViewController *shortCutVc = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcut];
            shortCutVc.delegate = self;
            [self presentViewController:shortCutVc animated:YES completion:nil];
        }
    }
    
    • 事件处理

    在appdelefate中监听,根据userActivity.activityType对不同的指令做相应的处理

    - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
    {
        if ([userActivity.activityType isEqualToString:@"com.cc.siri"]) {
            //代码块
        }
        return YES;
    }
    
    • 代理

    添加和修改有不同的代理,都要分别实现

    1. 添加 INUIAddVoiceShortcutViewControllerDelegate

    两个方法:

    
    /*!
     @abstract Called after the user finishes the setup flow for the voice shortcut, with either the successfully-added voice shortcut, or an error.
     @discussion Your implementation of this method should dismiss the view controller.
     */
    - (void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(nullable INVoiceShortcut *)voiceShortcut error:(nullable NSError *)error;
    
    /*!
     @abstract Called if the user cancels the setup flow; the voice shortcut was not added.
     @discussion Your implementation of this method should dismiss the view controller.
     */
    - (void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller;
    
    1. 修改 INUIEditVoiceShortcutViewControllerDelegate

    三个方法:

    /*!
    @abstract Called if the user updates the voice shortcut, with either the successfully-updated voice shortcut, or an error.
    @discussion Your implementation of this method should dismiss the view controller.
    */
    - (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didUpdateVoiceShortcut:(nullable INVoiceShortcut *)voiceShortcut error:(nullable NSError *)error;
    
    /*!
    @abstract Called if the user deletes the voice shortcut.
    @discussion Your implementation of this method should dismiss the view controller.
    */
    - (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didDeleteVoiceShortcutWithIdentifier:(NSUUID *)deletedVoiceShortcutIdentifier;
    
    /*!
    @abstract Called if the user cancelled; no changes were made to the voice shortcut.
    @discussion Your implementation of this method should dismiss the view controller.
    */
    - (void)editVoiceShortcutViewControllerDidCancel:(INUIEditVoiceShortcutViewController *)controller;
    

    注意

    • suggestedInvocationPhrase在分类里

    NSUserActivity的.h中并没有属性suggestedInvocationPhrase,该属性其实是在分类NSUserActivity+IntentsAdditions里面,需要导入头文件

    #import <Intents/NSUserActivity+IntentsAdditions.h>
    

    Intents/Intents.h中包含了#import <CoreSpotlight/CoreSpotlight.h>

    • 查询是否添加过指令时,下面代码新开了一个线程,拿到结果后需要返回主线程

    [[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {
      
    }
    

    相关文章

      网友评论

        本文标题:iOS12 Shortcuts

        本文链接:https://www.haomeiwen.com/subject/fjxsoftx.html