Siri Shortcuts intent 擴(kuò)展開發(fā)

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

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

第二步:編輯文件

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

選擇處理類別 generic 是直接運(yùn)行 項(xiàng)目,其他的需要操作

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

如果選擇了這個(gè)按鈕也是需要點(diǎn)擊后才開始執(zhí)行,不選擇則會(huì)直接運(yùn)行

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

這里添加你想要跟業(yè)務(wù)相關(guān)的字段


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

在這里直接設(shè)置 可以在添加快捷指令頁面顯示


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

編譯運(yùn)行绳泉,會(huì)在右側(cè)編輯欄看到


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

siriintent 就是你接下來需要用到的類
第二步:

添加intent ,創(chuàng)建intent 時(shí)候會(huì)提示是否同時(shí)創(chuàng)建intent UI疯趟,如果需要頁面展示選擇是

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

這塊就是你創(chuàng)建好之后的文件目錄

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

網(wǎng)上大多在講解在intentHandler類中 導(dǎo)入你的intent文件頭文件虏辫,你會(huì)發(fā)現(xiàn)此時(shí)會(huì)報(bào)頭文件找不到

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

注意:此時(shí)你就需要在targets-》build phases 中添加第一步你所創(chuàng)建的intentdefinition文件倘要,這樣你在intent文件導(dǎo)入頭文件時(shí)褐筛,就不會(huì)報(bào)錯(cuò)了类少,intent UI 中也需要這么做

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

第三步,代碼處理

在intenthandler中根據(jù)intent業(yè)務(wù)類型不同判斷處理邏輯

- (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]);
        }
    }
}

在這個(gè)類中 添加你的業(yè)務(wù)邏輯
再次注意: 如果你的的業(yè)務(wù)邏輯也需要涉及到http請(qǐng)求瞒滴,在 intent UI或者 intent 中的 info.plist文件中 添加
Allow Arbitrary Loads ---- yes

允許http請(qǐng)求

第五步曲梗,開始在你的主項(xiàng)目使用siri shourtcuts的地方添加調(diào)起代碼

//
//  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(@"用戶尚未對(duì)該應(yīng)用程序作出選擇赞警。");
                       break;
                   case INSiriAuthorizationStatusRestricted:
                       NSLog(@"此應(yīng)用程序無權(quán)使用Siri服務(wù)");
                       break;
                   case INSiriAuthorizationStatusDenied:
                       NSLog(@"用戶已明確拒絕此應(yīng)用程序的授權(quán)");
                       break;
                   case INSiriAuthorizationStatusAuthorized:
                       NSLog(@"用戶可以使用此應(yīng)用程序的授權(quán)");
                       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

這一小部分可以判斷本地是否已經(jīng)添加了快捷方式,如果添加就需要進(jìn)入編輯頁面虏两,如果沒有添加進(jìn)入到添加頁面

 [[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];
                   }
               });

最重要的一點(diǎn) 開啟siri權(quán)限愧旦,而且需要具有開發(fā)者證書才可以開始siri,自己的沒有繳費(fèi)的開發(fā)者證書是開啟不了的
定罢,然后在主項(xiàng)目的info.list中添加
Privacy - Siri Usage Description 權(quán)限

截屏2020-12-18 下午2.44.56.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末笤虫,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌琼蚯,老刑警劉巖酬凳,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異遭庶,居然都是意外死亡宁仔,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門峦睡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來翎苫,“玉大人,你說我怎么就攤上這事榨了〖宓” “怎么了?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵龙屉,是天一觀的道長(zhǎng)呐粘。 經(jīng)常有香客問我,道長(zhǎng)转捕,這世上最難降的妖魔是什么事哭? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮瓜富,結(jié)果婚禮上鳍咱,老公的妹妹穿的比我還像新娘。我一直安慰自己与柑,他們只是感情好谤辜,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著价捧,像睡著了一般丑念。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上结蟋,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天脯倚,我揣著相機(jī)與錄音,去河邊找鬼嵌屎。 笑死推正,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的宝惰。 我是一名探鬼主播植榕,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼尼夺!你這毒婦竟也來了尊残?” 一聲冷哼從身側(cè)響起炒瘸,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寝衫,沒想到半個(gè)月后顷扩,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡慰毅,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年屎即,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片事富。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡技俐,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出统台,到底是詐尸還是另有隱情雕擂,我是刑警寧澤,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布贱勃,位于F島的核電站井赌,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏贵扰。R本人自食惡果不足惜仇穗,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望戚绕。 院中可真熱鬧纹坐,春花似錦、人聲如沸舞丛。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽球切。三九已至谷誓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間吨凑,已是汗流浹背捍歪。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留鸵钝,地道東北人糙臼。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像蒋伦,于是被迫代替她去往敵國和親弓摘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容