Siri Shortcuts 指北
從 SiriKit 到 Siri Shortcuts
Apple 在 WWDC 2016 上推出了 SiriKit,使得開發者可以開發 app extension 讓使用者可以利用 Siri 完成特定的幾種任務。這裡有兩個基本概念:
Siri 會完成自然語言處理,理解使用者的意圖,並決定什麼時機來呼叫我們的 app extension,我們只需要告訴 Siri 是否可以處理這個 intent 並完成就可以了。Apple 為各個 domain 的 intents 提供了協議作為模板供開發者實現,以傳送資訊為例:
當用戶想用 Siri 傳送訊息時,系統會建立一個 INSendMessageIntent
,裡面包含訊息接受者、訊息內容等資訊,然後呼叫 app extension 的 handler,handler 解析這些上下文,確認可以處理併發送完訊息後返回 INSendMessageIntentResponse
型別的結果。
在 WWDC 2018 上,Apple 推出了 Siri Shortcuts 進一步拓展了 Siri 的使用場景。Siri Shortcuts 能讓使用者通過一句自定義的短語讓 Siri 完成自己經常進行的動作,比如檢視今天的天氣,叫一份外賣。與 SiriKit 最主要的不同點有兩個:
- 只針對具體的動作,不需要使用者提供資訊。可以理解成類和例項的關係。我們用 SiriKit 來打車,每次的出發地和目的地都不一樣;而 Siri Shortcuts 只完成打車回家這個具體的動作,永遠是從當前位置到家裡,使用者也就不需要再告訴 Siri 出發地和目的地。
- 可以用 Siri Shortcuts 完成的動作不限於 SiriKit 的幾個 domain。Siri Shortcuts 可以理解成為特定動作設定的一個快捷方式,因為 Siri Shortcuts 不涉及語義分析,也就不用對實現的動作做限制。
使用
假設我們有一個 app 叫小決定,用轉盤來幫助選擇困難症患者做決定。現在要為小決定新增 Siri Shortcuts 的支援。
定義 Shortcuts
首先,我們需要定義要完成的動作。Apple 用 INShortcut
來表示一個 shortcut,並提供了兩種方式初始化引數: NSUserActivity
和 INIntent
,用來封裝動作的上下文。
NSUserActivity INIntent
這裡只介紹第二種。
如果要實現的功能不屬於 SiriKit 支援的 domain,就需要建立一個自定義的 Intent。我們首先需要通過 File > New > File… 新建一個 SiriKit Intent Definition File 檔案,然後建立自己的 Intent
這裡依次填入基本資訊,重點是下方的 Parameters 和 Shortcut Types。Parameters 用來存放完成動作的上下文資訊,比如要點的咖啡種類、數量、選項(是否加冰等)。Shortcut Types 是 Parameters 的組合,比如“咖啡種類”和“咖啡種類加選項”,可以為不同的種類設定是否支援後臺執行。如果支援後臺執行,Siri 會呼叫 app extension 來完成動作。
這裡我們定義了一個 Intent 叫 MakeDecisionIntent
,它有兩個引數,決定的 id 和名稱。
定義完 Intent 之後需要定義 response。
在這裡可以定義一些 Properties,下面可以組合成不同的結果模板。系統提供了一些預設的錯誤碼,開發者也可以定義新的錯誤碼,Xcode 會為這些錯誤碼生成對應的程式碼。這裡我定義了一個 decisionNotFound
的錯誤碼,來代表 id 對應的決定找不到的情況,在響應 Shortcut 的時候需要特殊處理。
捐贈(Donate)Shortcuts
然後,我們需要告訴系統定義好的 shortcuts。
要使用 NSUserActivity
來 donate shortcuts,只需要將 isEligibleForPrediction
設定成 true 即可。用這種方法 donate,Siri 在匹配到 Shortcuts 後會 跳轉到 app 中 完成後續的操作。
如果使用的是 Intent,那麼在合適的時機(比如使用者剛剛決定今晚吃什麼),可以用 INInteraction
來 donate 「今晚吃什麼」這個 intent。在一段時間後,Siri 會找到使用者的行為模式(比如每週五下午都會做這個決定),會在「合適的時機」在鎖屏介面或者 Siri 的搜尋介面顯示這個 shortcut。
響應 Shortcuts
為了達到不離開 Siri 完成動作的目的,我們需要為 app 新增一個 Intent App Extension,跟其他型別的 App Extension 一樣是以獨立程序的形式執行的,因此編譯完成後跟主 app 是兩個獨立的二進位制檔案,可以將公用的邏輯以 framework 的方式共享。
在 Xcode 自動生成的 IntentHandler
中,有兩個方法需要實現:
func handler(for intent: INIntent) -> Any// 1 func handle(intent: MakeDecisionIntent, completion: @escaping (MakeDecisionIntentResponse) -> Void)// 2
方法一中需要返回一個 handler,在這裡就是 IntentHandler
本身。
方法二處理具體的邏輯。可以看到這個方法包含兩個引數,一個是之前 app donate 的 Intent,另一個引數是一個閉包,用來作為處理完成後的回撥。其中的 MakeDecisionIntent
和 MakeDecisionIntentResponse
都是 Xcode 自動生成的。如果使用者在添加了短語後刪除了對應的決定,就返回前面定義的 decisionNotFound
,這個時候 Siri 將前面定義好的錯誤資訊展示給使用者。
快捷短語
除此之外,使用者還可以主動為某個 shortcut 新增一個短語(類似語音命令),當用戶對 Siri 說出這個短語時,就會觸發相應 shortcut 的執行。 INIntent
有一個屬性叫做 suggestedInvocationPhrase
,用來為使用者提供短語的建議,這個短語應該儘可能簡潔並有區分度。
Apple 還特地為管理短語提供了一個 Add to Siri 按鈕(INUIAddVoiceShortcutButton)。這個按鈕統一了 Siri Shortcuts 短語的視覺和互動,使得使用者更容易接受。
使用者點按這個按鈕後會展示一個系統提供的介面,可以通過它新增、修改、刪除短語。
短語新增完成後就可以在 Siri 中使用了: