天天看點

Siri Shortcuts intent 擴充開發import "ViewController.h"import "SiriIntent.h"import <IntentsUI/IntentsUI.h>

直接開始

第一步: 添加檔案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 )parameters ofInteraction:(INInteraction )interaction interactiveBehavior:(INUIInteractiveBehavior)interactiveBehavior context:(INUIHostedViewContext)context completion:(void (^)(BOOL success, NSSet *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{

*/

  • (void)editVoiceShortcutViewControllerDidCancel:(INUIEditVoiceShortcutViewController *)controller{

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

[[INVoiceShortcutCenter sharedCenter] getAllVoiceShortcutsWithCompletion:^(NSArray _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;           
}
               }
                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 權限

繼續閱讀