Siri自定義Intent以及處理

tingdongli發表於2018-09-10

一、新建自定義Intent

1.Xcode->New->File->搜尋Intent

Siri自定義Intent以及處理
2.左下角'+'號新建Intent
Siri自定義Intent以及處理
3.完善Intent資料
Siri自定義Intent以及處理
注意:1.Intent的命名,如果命名為A,編譯之後,系統自動生成AIntent.h檔案,import AIntent.h即可使用。

2.Paramters:你想要Intent傳遞的資料,自定義即可。

3.ShortCut Types:根據傳入Intent的不同引數組合,生成不同的標題和副標題,主要用於在SpotLight中的顯示或鎖屏時的顯示。

4.Response:你需要response中傳遞的資料。

4.編譯

編譯之後,會自動生成Intent Class和Intent Response以及IntentHandling協議。例如Intent命名為A,編譯之後會自動生成AIntentAIntentResponseAIntentHandling協議(下文會用到),之後在App Extension中新建的處理AIntent的IntentHandler必須遵循AIntentHandling

二、使用自定義Intent

下述程式碼的作用是生成ShortCut,該ShortCut的型別是你自定義的Intent,執行下述程式碼之後,生成的ShortCut會在SpotLight或鎖屏時展示,前提是在iPhone 設定->Siri與搜尋中開啟搜尋建議,查詢建議,鎖屏建議,之後可以將ShortCut與使用者語音對應。

f (@available(iOS 12.0, *)) {
        TestIntent *testIntent = [[TestIntent alloc] init];
        testIntent.content = @"新生成的App內處理的ShortCutIntent";
        INInteraction *interaction = [[INInteraction alloc] initWithIntent:testIntent response:nil];
        [interaction donateInteractionWithCompletion:^(NSError * _Nullable error) {
            
        }];
    } else {
        // Fallback on earlier versions
    }
複製程式碼

注意程式碼中的content引數,和Intent中的Parameters對應

三、處理自定義Intent

使用者喊出語音之後,需要對其作出處理,分為App被處理和App Extension處理,區別是是否需要啟動App

1.App內處理

if([userActivity.interaction.intent isKindOfClass:[TestIntent class]]){
        ViewControllerA *viewControllerA = [[ViewControllerA alloc] init];
        //根據userActivity.interaction.intent.content不同做不同的處理。
        UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:viewControllerA];
        [self.window.rootViewController presentViewController:nav animated:YES completion:nil];
    }
複製程式碼

2.App Extension處理

(1)Xcode->New->Target->搜尋Intents Extension

(2)新建一個AIntentHandler來處理你自定義的AIntent,需要遵循上述的AIntentHandling協議。

TestIntentHandler.h

#import <Intents/Intents.h>
#import "TestIntent.h"

NS_ASSUME_NONNULL_BEGIN

@interface TestIntentHandler : INExtension<TestIntentHandling>

@end

NS_ASSUME_NONNULL_END
複製程式碼

TestIntentHandler.m

#import "TestIntentHandler.h"

@implementation TestIntentHandler

- (void)handleTest:(TestIntent *)intent completion:(void (^)(TestIntentResponse *response))completion NS_SWIFT_NAME(handle(intent:completion:)){
    NSUserActivity *userActivity = [[NSUserActivity alloc] initWithActivityType:NSStringFromClass([TestIntent class])];
    TestIntentResponse *response = [[TestIntentResponse alloc] initWithCode:TestIntentResponseCodeSuccess userActivity:userActivity];
    completion(response);
}

@end
複製程式碼

(3)在IntentHandler檔案中的handlerForIntent方法中新增自定義Intent的指定IntentHandler。

- (id)handlerForIntent:(INIntent *)intent {
    // 這是預設的實現,如果你想要不同的物件來處理不同的意圖,你可以覆蓋重寫
  if([intent isKindOfClass:[TestIntent class]]){
        TestIntentHandler *testIntentHandler = [[TestIntentHandler alloc] init];
        return testIntentHandler;
    }else{
        return self;
    }
}
複製程式碼

處理邏輯應該在AIntentHandler中編寫。

Demo地址

相關文章