iOS 10 SiriKit QQ 適配詳解

羅鑫發表於2016-10-20

1. 概述

蘋果在 iOS 10 開放了 SiriKit 介面給第三方應用。目前,QQ 已經率先適配了 Siri 的發訊息和打電話功能。這意味著在 iOS 10 中你可以直接告訴 Siri 讓它幫你發 QQ 訊息和打 QQ 電話了,聽起來是不是很酷炫?

那麼第三方應用使用 Siri 的體驗究竟如何?哪些應用可以接入 SiriKit?接入 SiriKit 又需要做哪些工作呢?這篇文章會為你一一解答這些疑惑。

圖1 用 Siri 發 QQ 訊息效果展示

2. SiriKit 簡介

我們都知道 Siri 是 iPhone 手機中的智慧語音助手,那麼什麼是 SiriKit 呢?SiriKit 是蘋果為第三方應用支援 Siri 提供的開發框架。在官方文件中,SiriKit 將對不同場景的語音支援劃分為不同的 domain,目前,SiriKit 支援的 domain 包括:VoIP 電話、發訊息、轉賬、圖片搜尋、網約車訂車、CarPlay 和餐廳預定,也就是說如果你的應用中包含有這些功能之一,就可以考慮將這些功能接入到 SiriKit 中啦。

實現 SiriKit 相關功能時,我們並不需要真正對語音進行識別,語音的識別工作會由 Siri 完成。Siri 識別完語音後,會將語音要完成的功能抽象成 Intent 物件傳遞給我們,而我們的接入工作主要是與這些 Intent 物件打交道,並不會涉及到自然語言處理(NLP)的技術。

關於 SiriKit 的開發網上已有一些文章(比如《SiriKit 初探 —— WWDC 2016 技術賞析》),也可參考蘋果的官方文件 SiriKit Programming Guide,本文著重介紹 QQ 的適配經驗。

圖2 SiriKit 原理

3. SiriKit 接入

要實現 SiriKit 的功能需要在 Xcode 工程中新增 Intents Extension 的 target,和其他 extension 一樣,Intents Extension 是一個獨立於 Containing App 程式執行的外掛,主要用於處理和確認來自 Siri 的 intent 請求。如果想讓 Siri 在處理 App 相關 intent 時提供一些自定義的介面,那麼你就需要再新增 Intents UI Extension 的 target,Intents UI Extension 也是一個獨立執行的外掛(所以要完整的支援 SiriKit 其實是需要新增兩個 target,有點蛋疼)。關於 App Extension 的開發可以參考蘋果的 App Extension Programming Guide

我們以 QQ 中的發訊息功能為例說明一下 SiriKit 的接入方法:

首先,我們需要在 Intents Extentsion 的 info.plist 檔案中配置須支援的 Siri Intents,在 IntentsSupported 中加入 INSendMessageIntent,如果需要在鎖屏時禁用某個功能,則再在 IntentsRestrictedWhileLocked 中加入相應項的 Intent,如圖3所示。

圖3 Intent Extentsion info.plist 配置
SiriKit 的接入主要分為 Intents Extension 和 Intents UI Extension 兩部分,下面分別進行介紹。

Intents Extension

當我們對 Siri 說“用 QQ 發訊息給王一然說你好”時,語音的識別將會由 Siri 自動完成,Siri 會將識別好的內容展示在 Siri 的介面。如圖4所示,我們可以看到一個完整的發訊息語句主要由四部分組成:

  1. 應用名:告訴 Siri 要使用哪個 App,Siri 會根據 App 的 bundle displayname 自動識別 App 的名稱,無需額外註冊。
  2. 發訊息 Intent:告訴 Siri 要使用發訊息的功能,我們實測發現說發資訊也是能識別,具體還有哪些詞彙會識別為發訊息的 intent 蘋果沒有在文件中說明。
  3. 訊息接收者:告訴 Siri 訊息的接收者是誰,“王一然”是我 QQ 好友的暱稱。
  4. 訊息內容:告訴 Siri 你要發的訊息內容是什麼,這裡的訊息內容為“我很生氣”。

圖4 確認傳送訊息介面
其中應用名和 Intent 是必須的,不然 Siri 無法抽象出你的“Intent”。後兩項如果預設的話,我們可以在實現中要求使用者進一步提供資料或者忽略。在識別完成後 Siri 會將訊息內容和接收者抽象成一個 INSendMessageIntent 傳遞給 QQ 的 Intent Extension。

我們從圖4還可以看到 Siri 準確從我的語音中識別出我 QQ 好友中暱稱為“王一然”的好友,然而“王一然”並不是一個通用的短語,那麼這是怎麼做到的呢?奧祕就在於在 QQ 執行時我們把所有 QQ 好友的暱稱同步到了 Siri 雲端,這樣 Siri 就可以識別出特定使用者要使用的特定短語,詳細同步方法可參考 INVocabulary 的setVocabularyStrings:ofType:方法。

每個 domain 的功能在 Siri 中都有對應的 Intents,而每個 intents 都對應一個特定的 handler 協議。對於發訊息來講,對應的 Intent 和 handler 協議分別為INSendMessageIntentINSendMessageIntentHandling。只要實現INSendMessageIntentHandling協議中的相關方法,並在 Siri 解析出INSendMessageIntent請求時用我們的INSendMessageIntentHandling物件去處理相關的發訊息請求。具體的流程如圖5:

圖5 Siri 發 QQ 訊息流程
1)ResolveRecipientsForSendMessage

對 Siri 從Intent中傳遞過來的接收者名稱進行處理和確認,比如可以確認該名稱當前是否在 QQ 好友列表中,並將 resolution result 反饋給 Siri。Resolution result 代表了應用對 intent 處理後的結果,對於發訊息來說,表1列舉了幾種可能的 resolution results。

表1 send resolution result
2)ResolveContent

與接收者的處理類似,在這個方法中可以對 Siri 識別出的訊息內容進行“修飾”,並且將 resolution result 反饋給 Siri,比如 QQ 對一些訊息裡面的特殊詞彙如“生氣”做了 emoji 適配。

3)ConfirmSendMessage

這個方法的作用是確認是否要傳送該訊息,可以在這一步進行一些鑑權工作,鑑權通過後再確認傳送,否則取消。確認可以傳送後會調起確認傳送介面,如圖4所示。如果需要從Containing App共享資料,具體的實現方案參考 App Group 的 Shared Container。

4)HandleSendMessage

如圖4,當使用者點選了“傳送”按鈕或者用語音給出了傳送指令時會最終進入到這個方法,在這個方法裡我們需要實現發訊息的邏輯,傳送成功後可以調起訊息傳送成功的介面,如圖6。

圖6 訊息傳送成功介面

Intents UI Extension

對於支援自定義介面的 Intent 型別,可以在 Intents UI Extension 中提供更美觀的自定義介面。 Custom UI 的實現相對較簡單,和 iOS App 的開發一樣,都是通過 UIViewController 的子類實現。我們需要在 Intents UI Extension 的 info.plist 檔案中設定 initial viewcontroller 或者設定 main storyboard,對於不同型別的 Intent 的介面展示,通過 Child Viewcontrollers 的方式實現差異化介面展示。

如圖7所示,當接收到來自 Intents Extension 的 response 時,系統會喚起 Intents UI Extension 並載入 initial viewcontroller,通過INUIHostedViewSiriProviding協議的configureWithInteraction:context:completion:方法可以獲取 intent,比如在發訊息功能中,在訊息確認傳送和傳送成功後都會回撥一次這個方法。根據 Intent 物件的型別和狀態,在收到相關 Intent 的回撥時 present 對應的 Child Viewcontroller 即可實現定製化的介面展示。

這裡需要注意的是,Intents UI Extension 的程式並不會在介面銷燬後就退出,很可能只是在後臺處於休眠狀態,下次 response 到來時再被喚醒。

圖7 Life cycle of an Intents UI extension

4. 總結

總的來說雖然蘋果這一次對 SiriKit 開放的場景有限,但是從我們的適配經歷來看蘋果對 Siri 還是非常重視的。另外,這是 SiriKit 首次對第三方應用開放介面,所以不可避免存在一些問題。我們在開發過程中也確實遇到了一些 SiriKit 本身的 Bug,大部分 Bug 在向蘋果反饋後都得到了解決,但是在語言識別方面 Siri 依然存在一些缺陷,比如對中英文混合的場景識別依舊不太好。期待以後 Siri 對中文的支援越來越好,也希望 Siri 能夠開放更多的場景給第三方應用適配。

相關文章