Siri Shortcuts intent 扩展开发

直接开始
第一步: 添加文件Sirikit Intent Definition File

截屏2020-12-18 下午2.26.15.png

第二步:编辑文件

截屏2020-12-18 下午2.27.52.png

选择处理类别 generic 是直接运行 项目,其他的需要操作

截屏2020-12-18 下午2.28.42.png

如果选择了这个按钮也是需要点击后才开始执行,不选择则会直接运行

截屏2020-12-18 下午2.29.55.png

这里添加你想要跟业务相关的字段


截屏2020-12-18 下午2.32.34.png

在这里直接设置 可以在添加快捷指令页面显示


截屏2020-12-18 下午2.33.22.png

编译运行,会在右侧编辑栏看到


截屏2020-12-18 下午2.40.36.png

siriintent 就是你接下来需要用到的类
第二步:

添加intent ,创建intent 时候会提示是否同时创建intent UI,如果需要页面展示选择是

截屏2020-12-18 下午2.38.32.png

这块就是你创建好之后的文件目录

截屏2020-12-18 下午2.42.03.png

网上大多在讲解在intentHandler类中 导入你的intent文件头文件,你会发现此时会报头文件找不到

截屏2020-12-18 下午2.42.55.png

注意:此时你就需要在targets-》build phases 中添加第一步你所创建的intentdefinition文件,这样你在intent文件导入头文件时,就不会报错了,intent UI 中也需要这么做

截屏2020-12-18 下午2.44.56.png

第三步,代码处理

在intenthandler中根据intent业务类型不同判断处理逻辑

- (id)handlerForIntent:(INIntent *)intent {
    if ([intent isKindOfClass:[SiriIntent class]]) {
        SiriIntentHandler * siriHander = [[SiriIntentHandler alloc]init];
        return siriHander;
    }
    
     // This is the default implementation.  If you want different objects to handle different intents,
    // you can override this and return the handler you want for that particular intent.
    
    return self;
}

第四步,在你的intentViewController 类中 修改定制你的UI

- (void)configureViewForParameters:(NSSet <INParameter *> *)parameters ofInteraction:(INInteraction *)interaction interactiveBehavior:(INUIInteractiveBehavior)interactiveBehavior context:(INUIHostedViewContext)context completion:(void (^)(BOOL success, NSSet <INParameter *> *configuredParameters, CGSize desiredSize))completion {
    // Do configuration here, including preparing views and calculating a desired size for presentation.
    SiriIntentResponse *rsp = (SiriIntentResponse *) interaction.intentResponse;
       SiriIntent *intent = (SiriIntent *)interaction.intent;
    if (rsp.code == SiriIntentResponseCodeSuccess) {
        self.name.text = @"成功";
      if (completion) {
          completion(YES, parameters, [self desiredSize]);
      }
    }else{
        self.name.text = @"开始";
        if (completion) {
            completion(YES, parameters, [self desiredSize]);
        }
    }
}

在这个类中 添加你的业务逻辑
再次注意: 如果你的的业务逻辑也需要涉及到http请求,在 intent UI或者 intent 中的 info.plist文件中 添加
Allow Arbitrary Loads ---- yes

允许http请求

第五步,开始在你的主项目使用siri shourtcuts的地方添加调起代码

//
//  ViewController.m
//  siri-intents
//
//  Created by david on 2020/11/27.
//  Copyright © 2020 david. All rights reserved.
//

#import "ViewController.h"
#import "SiriIntent.h"
  #import <Intents/Intents.h>
#import <IntentsUI/IntentsUI.h>
 @interface ViewController ()< INUIEditVoiceShortcutViewControllerDelegate,INUIAddVoiceShortcutViewControllerDelegate>

@property(nonatomic,strong) INUIAddVoiceShortcutViewController *customShortCutViewController;

@property(nonatomic,strong) SiriIntent *testIntent;
@property(nonatomic,strong) SiriIntentResponse *testIntentResponse;

@property(nonatomic,strong) INInteraction *interaction;

@property(nonatomic,strong) INShortcut *shortcut;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.title = @"SiriTest";
       if (@available(iOS 12.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;
               }
               
           }];
       }
    UIButton *_addSiriBtn = [[UIButton alloc] initWithFrame:CGRectMake(30, 151, 200, 50)];
    [_addSiriBtn setTitle:@"编辑siri" forState:UIControlStateNormal];
    [_addSiriBtn setTitleColor:UIColor.blueColor forState:UIControlStateNormal];
    [_addSiriBtn addTarget:self action:@selector(buildShortcutInCurrentViewController) forControlEvents:UIControlEventTouchUpInside];
    
    [self.view addSubview:_addSiriBtn];
   
 
    // Do any additional setup after loading the view.
}
 
-(void)buildShortcutInCurrentViewController
{
    self.testIntent = [[SiriIntent alloc] init];
//    self.testIntent.suggestedInvocationPhrase = @"";
    self.testIntent.name = @"张冲冲";
 
    
    self.interaction = [[INInteraction alloc] initWithIntent:self.testIntent response:nil];
    [self.interaction donateInteractionWithCompletion:^(NSError * _Nullable error) {
        if(error)
        {
            NSLog(@"%@",error);
        }
        else
        {
            NSLog(@"donate success");
        }
    }];
    
    if (@available(iOS 12.0, *)) {
           [[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {
               
               dispatch_async(dispatch_get_main_queue(), ^{
                   BOOL tempAddedShortcut = NO;
                   for (INVoiceShortcut *voiceShortcut in voiceShortcuts) {
                       NSLog(@"voiceShortcut.identifier = %@",voiceShortcut.identifier);
                       NSLog(@"voiceShortcut.invocationPhrase = %@",voiceShortcut.invocationPhrase);
                       NSLog(@"voiceShortcut.shortcut = %@",voiceShortcut.shortcut.userActivity.title);
                       NSLog(@"voiceShortcut.shortcut = %@",voiceShortcut.shortcut.userActivity.userInfo);

                       
                       if ([voiceShortcut.shortcut.intent isKindOfClass:[SiriIntent class]]) {
                           tempAddedShortcut = YES;
//                           break;
                       }
                   }
                    if (tempAddedShortcut) {
                        
                       INUIEditVoiceShortcutViewController *editVoiceShortcutViewController = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcuts[0]];
                       editVoiceShortcutViewController.delegate = self;
                       [self presentViewController:editVoiceShortcutViewController animated:YES completion:nil];
                   } else {
                      INShortcut *shortCut = [[INShortcut alloc] initWithIntent:self.testIntent];
                        
                          self.customShortCutViewController = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortCut];
                           self.customShortCutViewController.delegate = self;
                          [self presentViewController:self.customShortCutViewController animated:YES completion:nil];
                   }
               });
           }];
       }
   }

-(void)addVoiceShortcutViewControllerDidCancel:(INUIAddVoiceShortcutViewController *)controller
{
    [controller dismissViewControllerAnimated:YES completion:nil];
}

-(void)addVoiceShortcutViewController:(INUIAddVoiceShortcutViewController *)controller didFinishWithVoiceShortcut:(INVoiceShortcut *)voiceShortcut error:(NSError *)error
{
    [controller dismissViewControllerAnimated:YES completion:nil];
}
 
- (void)editVoiceShortcutViewController:(INUIEditVoiceShortcutViewController *)controller didUpdateVoiceShortcut:(nullable INVoiceShortcut *)voiceShortcut error:(nullable NSError *)error{
    [controller dismissViewControllerAnimated:YES completion:nil];

}

/*!
 @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{
    [controller dismissViewControllerAnimated:YES completion:nil];

}
 
 */
- (void)editVoiceShortcutViewControllerDidCancel:(INUIEditVoiceShortcutViewController *)controller{
    [controller dismissViewControllerAnimated:YES completion:nil];

}
 


@end

这一小部分可以判断本地是否已经添加了快捷方式,如果添加就需要进入编辑页面,如果没有添加进入到添加页面

 [[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray<INVoiceShortcut *> * _Nullable voiceShortcuts, NSError * _Nullable error) {
               
               dispatch_async(dispatch_get_main_queue(), ^{
                   BOOL tempAddedShortcut = NO;
                   for (INVoiceShortcut *voiceShortcut in voiceShortcuts) {
                       NSLog(@"voiceShortcut.identifier = %@",voiceShortcut.identifier);
                       NSLog(@"voiceShortcut.invocationPhrase = %@",voiceShortcut.invocationPhrase);
                       NSLog(@"voiceShortcut.shortcut = %@",voiceShortcut.shortcut.userActivity.title);
                       NSLog(@"voiceShortcut.shortcut = %@",voiceShortcut.shortcut.userActivity.userInfo);

                       
                       if ([voiceShortcut.shortcut.intent isKindOfClass:[SiriIntent class]]) {
                           tempAddedShortcut = YES;
//                           break;
                       }
                   }
                    if (tempAddedShortcut) {
                        
                       INUIEditVoiceShortcutViewController *editVoiceShortcutViewController = [[INUIEditVoiceShortcutViewController alloc] initWithVoiceShortcut:voiceShortcuts[0]];
                       editVoiceShortcutViewController.delegate = self;
                       [self presentViewController:editVoiceShortcutViewController animated:YES completion:nil];
                   } else {
                      INShortcut *shortCut = [[INShortcut alloc] initWithIntent:self.testIntent];
                        
                          self.customShortCutViewController = [[INUIAddVoiceShortcutViewController alloc] initWithShortcut:shortCut];
                           self.customShortCutViewController.delegate = self;
                          [self presentViewController:self.customShortCutViewController animated:YES completion:nil];
                   }
               });

最重要的一点 开启siri权限,而且需要具有开发者证书才可以开始siri,自己的没有缴费的开发者证书是开启不了的
,然后在主项目的info.list中添加
Privacy - Siri Usage Description 权限

截屏2020-12-18 下午2.44.56.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,082评论 5 464
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,231评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,047评论 0 327
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,977评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,893评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,014评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,976评论 3 388
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,605评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,888评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,906评论 2 314
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,732评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,513评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,980评论 3 301
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,132评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,447评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,027评论 2 343
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,232评论 2 339

推荐阅读更多精彩内容