SiriKit預研

一、SiriKit介紹

Siri是一款蘋果 iOS 系統提供的智能語音助手軟件,它的全名是 Speech Interpretation and Recognition Interface。2011年 Siri第一次以 iOS 內置軟件的形式隨 iPhone 4s 一同問世之后,終于在 WWDC 2016 上,蘋果開放了Siri 的 API,開發者們可以利用SiriKit將自己的服務提供給用戶。
備注:SiriKit是系統調用,是一個語義處理結合擴展UI的框架,不是語音轉文字的框架。SiriExtensionDemo

1、SiriKit提供11類服務領域,詳情請見蘋果官方文檔

SiriKit 服務領域(Domain) 對應的意圖(Intent)
語音和視頻通話 (VoIP calling) INSearchCallHistoryIntent、INStartAudioCallIntent、INStartVideoCallIntent
發送消息 (Messaging) INSendMessageIntent
收款或者付款 (Payments) INSendPaymentIntent、INRequestPaymentIntent
列表和筆記 (Lists and Notes) INCreateNoteIntent、INAppendToNoteIntent
視覺編碼 (Visual Codes) INGetVisualCodeIntent
圖片搜索 (Photo search) INSearchForPhotosIntent
管理鍛煉 (Workouts) INEndWorkoutIntent、INPauseWorkoutIntent 、INStartWorkoutIntent 、 INResumeWorkoutIntent 、INCancelWorkoutIntent
行程預約 (Ride booking) INRequestRideIntent、INGetRideStatusIntent、 INListRideOptionsIntent、 INGetRideStatusIntent
車載管理 (Car Commands) INGetCarLockStatusIntent、INSetCarLockStatusIntent、INActivateCarSignalIntent
車載系統 (CarPlay) INSetAudioSourceInCarIntent、 INSetClimateSettingsInCarIntent、 INSetSeatSettingsInCarIntent、INSaveProfileInCarIntent、INSetProfileInCarIntent、INSetRadioStationIntent
餐廳訂位 (Restaurant Reservations) INBookRestaurantReservationIntent、 INGetAvailableRestaurantReservationBookingDefaultsIntent、 INGetAvailableRestaurantReservationBookingsIntent、 INGetRestaurantGuestIntent、 INGetUserCurrentRestaurantReservationBookingsIntent

簡單來說,在SiriKit的開發功能基本上就是在蘋果提供的這些領域(Domain)上,在App開發中需要開發哪種領域的功能,就要在對應的plist文件中添加對應的Intent支持(具體在哪個plist文件下文有說明)那什么是Intent
備注:SiriKit不是萬能的,語義的處理流程要按照蘋果的套路來(應用領域,意圖),界面UI也套路來,不能調用App內部頁面,具體UI會有SiriKit的UI擴展來實現。

2、Intent的說明

要想了解Intent,首先要清楚SiriKit的外部工作流程:
1)、 Siri完成語音識別和語義分析;
2)、會根據你詞匯中的關鍵詞識別出你屬于上述11種領域中的哪一種;
3)、然后將結構化語音分析結果打包成一個某個領域(Domain)的意圖(Intent);
4)、接著交給支持這個意圖(Intent)的第三方應
用,第三方應用被啟動,從 傳入的Intent中獲取相應的信息,完成操作。
整個宏觀的流程如下圖:

例如,上圖演示中提到了的例句 “用演示發消息給小明",
領域 (Domain):Messaging
意圖 (Intent):Send a message (INSendMessageIntent)
意圖參數 (Intent Parameter)
收件人(recipients):小明
消息內容(content):空
備注:(appname:演示。如果沒有消息內容,這時就會涉及到Sikit的API中提供的處理機制,這個機制會調Siri反問你要發送什么內容,這個就涉及到下文提到的SiriKit相關功能和處理流程,會有不同的擴展和類在處理這個問題)

二、SiriKit功能開發介紹

1、發消息意圖API(舉例)

1)、發消息INSendMessageIntent配置

涉及到SiriKit的基本項目文件:

2)、發消息INSendMessageIntent相關協議方法

一個標準的意圖語音被Siri識別之后,SiriKit會先進入一個繼承于INExtension的指定意圖流程入口(NSExtensionPrincipalClass)類IntentHandler.m(默認類)。下面在這個相關類會處理整個流程:

方法列表 中文解釋
-resolveRecipientsForSendMessage:withCompletion: 解析發送消息語義,提取意圖對象
- resolveContentForSendMessage:withCompletion: 解析發送消息內容方法
- confirmSendMessage:completion: 確認方法
- handleSendMessage:completion: 處理方法

意圖的生命周期如下圖文描述:

一個典型的Intent事件的處理過程中有這三個步驟ResolveConfirmHandle

  1. Resolve階段。在Siri獲取到用戶的語音輸入之后,生成一個INIntent對象,將語音中的關鍵信息提取出來并且填充對應的屬性。這個對象在稍后會傳遞給我們設置好的INExtension子類對象進行處理,根據子類遵循的不同協議來選擇不同的解決方案。

  2. Confirm階段。在上一個階段通過handlerForIntent:(INIntent *)返回了處理Intent的對象,此階段會依次調用confirm打頭的實例方法來判斷Siri填充的信息是否完成。匹配的判斷結果包括Exactly one matchTwo or more matches以及No match三種情況。這個過程中可以讓Siri向用戶征求更具體的參數信息。

  3. Handle階段。在confirm方法執行完成之后,Siri進行最后的處理階段,生成答復對象,并且向此Intent對象確認處理結果然后執顯示結果給用戶看。

3)、發消息INSendMessageIntent的意圖對象

具體在各個階段的方法里怎么代碼實現,主要是要理解INSendMessageIntent的對象屬性,通過解析對象,可以在各個階段用獲取到的對象進行相關程序邏輯編碼。如:

對象名稱 類型 備注
recipients NSArray<INPerson*> Contacts to whom the message should be sent.
content NSString Body text of the message.
groupName NSString Body text of the message.
serviceName NSString Specified service for the message.
sender INPerson The person, or account, sending the message.

通過流程方法里獲取到INSendMessageIntent對象進行解析,匹配,處理,這個過程還涉及到返回的處理。每一個解析方法都需要得到一個INIntentResolutionResult類型的實例,用來保存校驗結果。

INIntentResolutionResult及其子類有不同的構造方法生成不同類型的結果,用來指定和Siri的交互。

值類型 INIntentResolutionResult 說明
+ (instancetype)needsValue; 需要一個值,Siri會提示用戶給一個值
+ (instancetype)notRequired; 不是必要的,是否給值都會過這個resolve
+ (instancetype)unsupported; 不支持的,Siri會提示用戶這個值不被支持
+(instancetype)successWithResolvedValue:(BOOL)resolvedValue; 成功解析
+(instancetype)confirmationRequiredWithValueToConfirm:(nullable NSNumber *)valueToConfirm; Siri提示用戶確認當前是否是一個bool值

當一個intent的所有參數都成功解析了,處理程序就會向用戶詢問是否確認這個intent的細節,并且提供一個建議響應。當所有參數被成功解析后,或者在不要求所有參數進行解析,那么就認為是解析成功。
在確認期間,就可以執行所有的intent參數的附加驗證,以確保你可以使用該信息來執行所請求的服務。如果之前的解析函數是單元測試,那么這個確認函數就是集成測試,保證所有輸入參數正確。

最后一個處理intent的階段,就是執行與這個intent相關的動作。在-handleSendPayment:completion函數中做相應業務邏輯,需要注意的是你在Extension中做的修改也應當反應到App主程序當中,所以需要提供任務的數據給到App。SiriKit提供了一個包含intent細節(INIntent、INIntentResponse)InInteraction對象,你可以使用userActivityInstance.interaction得到它,在App啟動時調用
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler
函數處理來自Extension的數據。

4)、根據流程方法處理之后,如何與主程序通信

輕量級通信可采用這個辦法:
1)、在handling階段在NSUserActivity存儲相應的信息,字典或字符串都行(如上handling階段代碼)。
2)、在AppDelegate,獲取NSUserActivity所存儲的信息。
3)、發送通知給所需要的地方。
4)、接收到通知后對主程序進行相應操作。

備注:確認消息發送之后的邏輯也可以在處理階段編碼解決

有關在AppDelegate中處理SiriKit的Intent可以參考相關蘋果官方文檔

//AppDelegate.m
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    return NO;
}
- (BOOL)application:(UIApplication *)application
   continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray *restorableObjects))restorationHandler {
    if ([userActivity.interaction.intent isKindOfClass:[INSendMessageIntent class]]) {
        INSendMessageIntent *intent = (INSendMessageIntent *)(userActivity.interaction.intent);
        NSLog(@"%@",[[intent.recipients lastObject] displayName]);
    }
    return YES;
}

2、自定義界面(Intent UI Extension)

運用SiriKit開發相關功能,UI是依賴于Intent UI ExtensionSiriKit并不能從系統層面調用App內部UI,只能調用打開App和SirKit自定義UI

系統創建了ViewController,加載視圖,調用viewDidLoad方法并且調用了INUIHostedViewControlling協議的configureWithInteraction:context:completion:方法,傳遞了一個交互對象,用于配置界面。 當配置完成后,ViewController就會展示在Siri或者Maps應用界面的空白部分。這時會調用viewWillAppear/viewDidAppear方法。
當視圖消失時,也會調用生命周期的viewWillDisappear/viewDidDisappear方法。

關于控制器的使用,蘋果給出了幾點注意事項:

  1. 切換子控制器來展示不同類型的內容。 你的Intents UI擴展只有一個主視圖控制器,如果你想為不同的Intents展示不同的內容,你需要使用不同的視圖。可以在configureWithInteraction:context:completion:這個方法里面,根據提供的intentObject來創建不同的子視圖。
  1. 在你的視圖控制器可用的期間,動態調整內容。 在 viewDidAppear:方法里面才開始啟動動畫,在viewWillDisappear: 方法里面要結束動畫。
  1. 盡快的配置好你的視圖控制器,這樣Siri才能更快的展示它。 你的視圖控制器也許不會在屏幕上停留太久,所以盡量利用本地資源以及提供的INInteraction對象來配置你的設置。如果你需要從服務器拉取更多的信息,請異步完成,并在稍后再更新你的界面。
  1. 請不要在界面里面展示廣告。你可以展示你自己的品牌信息,但是你不能夠加入其它廣告。

三、結束

本文Demo:SiriExtensionDemo
發消息例子:
Siri說:“用演示給小明發消息”

轉賬例子:
Siri說:“用演示轉賬100元給孫波”

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,505評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,556評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,463評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,009評論 1 312
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,778評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,218評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,281評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,436評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,969評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,795評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,993評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,537評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,229評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,659評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,917評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,687評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,990評論 2 374

推薦閱讀更多精彩內容