標籤:

知乎 SiriKit 實戰

文章首發於《程序員》雜誌,轉載請註明出處。

寫在前面

1983年,一小部分開發者首要來到加州蒙特瑞(Monterey)見證了第一款蘋果公司設計的個人電腦的誕生。有趣的是這場會議並不對外開放,甚至是完全保密的,蘋果可以避開了媒體和公眾的視線,與會者甚至要簽署嚴格的保密協議。

官方意義上的 WWDC 開始於1990年,而對於國內早期的 iOS 開發者來說,對 WWDC 最早的記憶應該是從2007年第一代 iPhone 橫空出世開始的,到今天已經走過了9個年頭,iOS 系統的版本號也已經到了兩位數。相比於 iOS7 開始每個 iOS 版本大刀闊斧的革新,今年的 iOS 10 更加專註於對現有功能的改進,最大的亮點無疑是 SiriKit 對開發者開放,本文也著重介紹以下 SiriKit 的設計理念和實踐。

SiriKit 簡介

Siri 是一款蘋果 iOS 系統提供的智能語音助手軟體,它的全名是 Speech Interpretation and Recognition Interface。用語音和 Siri 交互可以讓你實現傳送訊息、安排會議、撥打電話、查看附近餐廳等功能,並且全程都是 Hand Free 的;你還可以讓 Siri 學習你的聲紋,然後通過「嘿 Siri」來激活它。

從2011年 Siri 第一次以 iOS 內置軟體的形式隨 iPhone 4S 一同問世之後,蘋果一直致力於更新改進以使它更智能,iOS 的開發者們也一直期盼有一天自己的 App 也可以利用到 Siri 帶來好處和便利。終於在 WWDC2016 上,蘋果開放了 Siri 的 API,開發者們可以利用 SiriKit 將自己的服務提供給用戶。蘋果為了保護 iOS 的用戶體驗,在 API 的開放上一向非常謹慎, SiriKit 也不例外。利用 SiriKit 開發者目前只能做如下六件事情:

  • 語音和視頻通話
  • 發送消息
  • 發送或者接收付款
  • 照片搜索
  • 打車
  • 管理健身

SiriKit 將上述六種行為描述為六種類型的意圖(Intents),提供對應的 Intent.framework 和用於 UI 展示的 IntentUI.framework 兩個工具包方便開發者實現上述功能。

如果你的應用剛好在這些領域之內,那麼恭喜你可以使用 SiriKit 為你的應用增加系統級的入口、提升用戶體驗,並且能夠在地圖這樣的系統應用中使用你的服務(WWDC 兩個 Siri 的 Session 中也都提到了這一點),無論你的應用進程是在後台運行,還是已經被 Kill。

SiriKit 設計初探

先來看下面一段對話:

  • 你:用知了給 Jon Snow 發一條消息
  • Siri:消息的內容是?
  • 你:Winter is coming

這是 Siri 消息類型意圖的典型使用場景。然而用戶的行為總是不可確定的,在發送一條消息給 Snow 的時候你也可能會這樣說:

  • 你:用知了發送一條消息
  • Siri:給誰發?
  • 你:Jon Snow
  • Siri:發送的內容是?
  • 你:Winter is coming

Intent 處理流程

當然還有支付、打車等場景,為了適應各種複雜的交互場景,SiriKit 將每種意圖的處理總結為如下過程:

  • Speech:用戶對 Siri 說了一句話,Siri 通過人工智慧技術識別用戶的意圖(Intent)
  • Intent:如果 Siri 發現用戶的意圖屬於已支持的六種行為之一,並且信息內容中包含你的 App,就會把當前的信息內容轉發給 App;
  • Action:App 在後台收到這個 Intent 之後開始針對這個 Intent、通過 Siri 向用戶進行必要的信息採集、加工、處理,並完成用戶的意圖;?每種意圖下採集的信息不盡相同,發送消息需要採集的信息如下:
    • Domain:Messages
    • Intent:sendMessage
    • App:ZhiChat
    • Recipient:Jon Snow
    • Content:Winter is coming
  • 而對於支付採集收集的信息可能有:
    • Domain:Payments
    • Intent:sendPayment
    • App:ZhiPay
    • Payee:Daenerys Targaryen
    • Amount:100
    • Currency:RMB
    • Note:Buy clothes
  • Response:用戶意圖處理完成後,Siri 將處理結果(成功或失敗)展現給用戶。

Intent 的生命周期

SiriKit 將底層的深度學習、CNN 等技術封裝起來,開發者只需要關注自己如何提供服務,如何滿足用戶需求。因此 SiriKit 的實現代碼大部分是圍繞用戶意圖(Intent)來完成的,在前文所述的過程中,每個意圖的生命周期可分成如下三個階段:

  • Resolve:App 處理 Siri 收集到的用戶信息並反饋給 Siri。開發者需要針對不同意圖實現不同的 Resolve 方法,在 Intent 的生命周期中 Resolve 動作可能發生多次。每個 Resolve 方法執行後都需要反饋處理結果給 Siri。
  • Confirm:這一階段主要實現兩件事情。
    • 反饋給 Siri 當前意圖期望的結果;
    • 檢查完成意圖所需要的必要狀態,比如:
      • 雲端服務是否可用;
      • 當前用戶是否已登錄;
      • 付款時當前賬戶是否有足夠的餘額。
    • Siri 會根據當前信息決定是否展示給用戶一個確認窗口,比如付款時的確認窗口或者消息的發送窗口。Confirm 階段也會出現多次,根據實際經驗經驗每次 Resolve 方法調用後都會調用一次 Confirm 方法。
    • Handle:在收集到足夠信息之後,處理用戶的意圖並展示結果。通常情況下 handle 方法只會調用一次。如果這個處理過程中有網路請求,則需要提供處理狀態的 UI,並在儘可能短的時間內完成處理並將結果反饋給 Siri。

SiriKit 實戰

引入 SiriKit

和通知中心插件、Watch 擴展一樣,SiriKit 也是通過 Extensions 的方式與主 App 結合起來。SiriKit 提供了兩個新的擴展:

  • Intents Extension
  • Intents UI Extension

同時為了讓 App 更好的支持特定意圖的語義識別,App 可以在自定義詞表中提供一些 App 相關的術語和短句,這一點在後面的小節會有詳細說明。

在 Xcode8 中點擊 TARGETS 界面左下角的加號新建一個 Target,可以看到新版本的 Xcode 中蘋果為我們提供了茫茫多新的 extension 模板,選擇 Intents Extension。

點擊下一步,填寫 Product Name,選擇語言版本,注意,這裡有個「Include UI Extension」的選項,勾選之後會自動創建一個「Intents UI Extension」的 Target 用於 Siri 中的界面展示。

點擊完成。Xcode8會生成兩個 Target 和對應文件夾。

在主 App 支持 Siri

在 Capabilities 中打開 Siri 的開關,如果使用 Xcode8 並且 App 已經設置為自動管理 App Signing(Xcode8的又一重大革新),Xcode 會自動更新相應的證書文件,完成後如下圖:

修改 .entitlements 文件添加 Siri 支持:

指定 Intents Extension 支持的一種或多種 Intents

Intents Extension Target 創建後默認生成了兩個文件:

  • swift
  • plist

編輯 Intents Extension 的 Info.plist 文件,在 NSExtension 字典中指定 App 支持的意圖類型。以消息類型意圖為例 Intents Extension 的 Info.plist 如下:

解釋一下 plist 中的關鍵字:

  • IntentsSupported:支持的 Intents 類型列表;
  • IntentsRestrictedWhileLocked:限制使用該 Intents 前必須解鎖,也是一個列表;
  • NSExtensionPointIdentifier:必須為apple.intents-service;
  • NSExtensionPrincipalClass:Intents 擴展的入口文件,默認為$(PRODUCT_MODULE_NAME).IntentHandler。

打開IntentHandler.swift文件,部分默認實現如下:

我們先來運行測試一下。

在return self一行打上斷點,然後選擇 Intents Extension 對應的 Target,在 iOS 10 的設備上運行。此時會彈出一個 iPhone App 列表,選擇 Siri,編譯運行後會自動打開 Siri。

測試 Demo 中主 App 的名字為「知了」,在 iPhone 上打開的 Siri 界面輸入語音「使用知了發送一條消息」,Siri 會在這條語音中識別出用戶意圖為使用「知了」發送消息,將語音信息轉換為文本轉發給 Demo App,程序會停留在我們剛才設置的斷點上。

SiriKit 對中文的支持效果並不理想,例如語音輸入用知了發送一條消息,會將一條消息識別為發送的內容;再比如輸入用知了發消息給宏昌,會將發消息給宏昌識別為發送的內容。

經過多次測試,官方 Session 中示例中動詞化應用名字的方式識別效果最好。因此在 SiriKit 的中文語音測試中推薦如下形式:

你:知了發信息給宏昌。

Siri你想對宏昌說什麼。

你:看冰與火之歌了嗎。

Siri好的。可以發送了嗎?

你:發送。

Intents Lifecycle 編碼實現

停止運行,接下來來看一下具體的編碼實現。

為了當支持多重 Intents 時的代碼看起來簡潔,我們把不同類型的 Intent 轉發到不同的類。新建SendMessageIntentHandler類。

class SendMessageIntentHandler: NSObject, INSendMessageIntentHandling

在IntentHandler.swift中更新handler(for intent:)方法,在 Intent 為INSendMessageIntent時返回它。

override func handler(for intent: INIntent) -> AnyObject { // 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. if intent is INSendMessageIntent { return SendMessageIntentHandler() } return self}

具體的業務邏輯在SendMessageIntentHandler類實現。

resolve

resolve 是 Intent 處理邏輯的第一個階段。消息發送類型的意圖處理過程中,需要 resolve 的信息有兩個:

  • 消息接收者(Recipients),對應 resolve 方法是:resolveRecipients(forSendMessage intent:, with completion:)
  • 消息內容(Content),對應 resolve 方法是:resolveContent(forSendMessage intent:, with completion:)

可以看到,resolve 方法的參數主要有兩個:

  • INSendMessageIntent類型的實例intent,通過它可以訪問到所有 Siri 解析出的用戶意圖相關信息,如:消息接受者的信息recipients、消息內容intent.content等;
  • completion方法,用於返回當前的處理結果。根據處理結果的不同 SiriKit 設計了7個回調方法:?- success(with:) // 已完成必要信息的收集,可以進入下一階段
  • - confirmationRequired(with:) // 需要 Siri 提示用戶確認某些信息,如:消息接收者
  • - disambiguation(with:) // 有歧義的信息,如:命中了多個消息接收者
  • - needsMoreDetails(for:) // 目前的信息不足以完成 Intent 對應的操作,需要 Siri 繼續收集,如:希望提供消息接受者更多的信息
  • - needsValue() // 需要一個完成操作必要的值,如:付款的金額
  • - notRequired() // 告知 Siri 無論用戶是否對當前參數傳值都可以繼續執行
  • - unsupported() // 告知用戶當前值不支持,如:找不到消息接收者

如何合理的使用上述回調方法呢?舉例來說,消息接受者的 resolve 過程中可能發生的情況有三種:

  • 與消息接受者匹配的聯繫人被找到且只有一個,匹配成功,返回.success(with:recipientMatched);
  • 可能與消息接受者匹配的聯繫人有多個,匹配具有不確定性,返回.disambiguation(with: disambiguationOptions);
  • 未找到與消息接受者匹配的聯繫人,返回.unsupported()。

注意:一條消息的接收者可能有多個,因此消息接受者處理中completion方法的參數是一個內容類型為INPersonResolutionResult的數組,而不是單一結果。

消息內容的處理則比較簡單,判斷輸入內容是否合法後在completion方法中輸入INStringResolutionResult類型的結果並調用。

以下是 resolve 階段完整的代碼實現:

// 1.1 Resolve: 處理聯繫人信息func resolveRecipients(forSendMessage intent: INSendMessageIntent, with completion: ([INPersonResolutionResult]) -> Void) { if let recipients = intent.recipients { var resolutionResults = [INPersonResolutionResult]() for recipient in recipients { let matchingContacts = contacts(personName: recipient.displayName) switch matchingContacts.count { case 2 ... Int.max: let disambiguationOptions: [INPerson] = matchingContacts.map { contact in return contact } resolutionResults += [.disambiguation(with: disambiguationOptions)] case 1: let recipientMatched = matchingContacts[0] resolutionResults += [.success(with: recipientMatched)] case 0: resolutionResults += [.unsupported()] default: break } } completion(resolutionResults) } else { completion([INPersonResolutionResult.needsValue()]) }}// 1.2 Resovle: 處理消息內容信息func resolveContent(forSendMessage intent: INSendMessageIntent, with completion: (INStringResolutionResult) -> Void) { if let text = intent.content where !text.isEmpty { completion(INStringResolutionResult.success(with: text)) } else { completion(INStringResolutionResult.needsValue()) }}

confirm

每個 resolve 方法調用後都會調用 confirm 方法, Demo 中只檢查了當前的登錄狀態,當然你也可以在 confirm 中檢查更多的狀態。

// 2. Confirm:func confirm(sendMessage intent: INSendMessageIntent, completion: (INSendMessageIntentResponse) -> Void) { // 登錄後才能發消息 if hasValidAuthentication() { completion(INSendMessageIntentResponse(code: .success, userActivity: nil)) } else { let userActivity = NSUserActivity(activityType: String(INSendMessageIntent.self)) userActivity.userInfo = [NSString(string: "error"):NSString(string: "UserLoggedOut")] completion(INSendMessageIntentResponse(code: .failureRequiringAppLaunch, userActivity: userActivity)) }}

confirm 的參數仍然是intent和completion,completion方法的參數類型為INSendMessageIntentResponse。在應用邏輯中,檢查到用戶未登錄時,response 的code會傳入failureRequiringAppLaunch,即需要啟動 Demo 應用完成後續的登錄操作。SiriKit 提供了如下 code:

  • unspecified
  • ready
  • inProgress
  • success
  • failure
  • failureRequiringAppLaunch

值得注意的是除了code外,response 還接受另一個參數userActivity,它是一個NSUserActivity類型的對象,主要用於在主 App 啟動時將當前環境上下文傳遞給主 App。

handle

多次交互確認發送消息所需要的信息之後,Siri 會詢問我們「要發送嗎?」。語音輸入「好的」、「發送」或者「確定」都可以觸發發送。此時 SiriKit 會調用handle(sendMessage intent:, completion:)方法,消息發送的處理邏輯都應該在這個回調方法中完成。

// 3. Handle:func handle(sendMessage intent: INSendMessageIntent, completion: (INSendMessageIntentResponse) -> Void) { if intent.recipients != nil && intent.content != nil { let success = sendMessage(target: intent.recipients, content: intent.content) completion(INSendMessageIntentResponse(code: success ? .success : .failure, userActivity: nil)) } else { completion(INSendMessageIntentResponse(code: .failure, userActivity: nil)) }}

處理的結果通過INSendMessageIntentResponse返回給 SiriKit。

至此, SiriKit 的接入工作就完成了,但是用戶看到的是 SiriKit 提供的默認 UI,為了提供更好的用戶體驗,使界面風格契合 App 的特點,SiriKit 提供了自定義 UI 界面的擴展 —— Intents UI Extension。

Intents UI Extension

一個 Intents UI Extension 的完整生命周期如下:

在上面的小節中我們已經創建過 Intents UI Extension 的 Target,默認包含三個文件:

  • swift
  • storyboard
  • plist

基礎視圖的實現

和 Intents Extension 一樣,我們需要修改 Intents UI Extension 的 Info.plist 中NSExtension部分以支持INSendMessageIntent:

解釋一下 plist 中的 key:

  • IntentsSupported:支持的 Intents 類型列表;
  • NSExtensionMainStoryboard:Extension 視圖的 Storyboard;
  • NSExtensionPointIdentifier:必須為apple.intents-ui-service。

我們還是先來運行一次看看效果。在 Storyboard 中添加一個文本內容為「Winter is coming」的 UILabel,再次運行,效果如下:

Intents UI 的實現

視圖的邏輯編碼在IntentViewController類中,IntentViewController是UIViewController的子類,因此你可以使用所以UIKit的 API。也就是說,在這個類中編寫界面和我們之前開發過的 ViewController 編寫方式基本一致。

那麼 Intents Extension 在處理 Intent 過程中所發生的狀態變化是如何傳遞給 Intents UI 的呢?先來看一下IntentViewController類的基本實現:

class IntentViewController: UIViewController, INUIHostedViewControlling, INUIHostedViewSiriProviding { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } // MARK: - INUIHostedViewControlling // Prepare your view controller for the interaction to handle. func configure(with interaction: INInteraction!, context: INUIHostedViewContext, completion: ((CGSize) -> Void)!) { // Do configuration here, including preparing views and calculating a desired size for presentation. if let completion = completion { completion(self.desiredSize) } } var desiredSize: CGSize { return self.extensionContext!.hostedViewMaximumAllowedSize } var displaysMessage: Bool { return true } }

IntentViewController類繼承於UIViewController之外,還實現了INUIHostedViewControlling協議的 configure 方法。

configure(with interaction:, context:, completion:

這個方法的第一個參數是當前這次 Siri 交互上下文信息,包括 intent 和 intentResponse 等屬性,UI 層可以根據上下文信息完成本次視圖的更新展現(如:展示載入動畫),並返回一個CGSize給 Siri 來指明目前視圖的大小。NSExtensionContext中給出了視圖大小的最小和最大允許值,返回的CGSize只能在兩者之間。

var desiredSize: CGSize { return self.extensionContext!.hostedViewMaximumAllowedSize}

每次 Siri 和 App 交互後都會順序調用viewDidLoad()方法和configure()方法。另外,值得注意的是 Intents UI Extension 的界面區域內是不支持手勢交互操作的。

INUIHostedViewSiriProviding

從上文的截圖可以看到,除了你的自定義 UI 區域,Siri 還提供了一個默認區域展示消息的接收者和內容,如果我們在自定義區域已經展示了這些信息,這個默認區域會導致信息重複。SiriKit 為此提供了INUIHostedViewSiriProviding這個協議,通過實現代理方法可以隱藏這個區域:

var displaysMessage: Bool {

return true

}

隱藏後效果如下:

語義識別優化

官方的 Session 中簡單介紹了 Siri 識別當前的語義的一些依據:

  • 用戶必須顯示的說出你的應用名稱(即 Bundle display name);
  • 你的 App 名稱可以出現在一句話的任意位置,前提是不會引起歧義;
  • Siri 可以動詞化你的 App 名稱,如:知了 Jon Snow 一條消息。

SiriKit 處理的四個過程裡面,App 的處理邏輯主要是從 Intent 過程開始的。Speech 過程由 Siri 獨立完成,考慮到每個 App 都有自己獨特的方式和用戶交流,因此在語義識別的過程中,Siri 允許應用提供自定義的詞表(User vocabulary )用來幫助 Siri 更好識別和 App 相關的語境。

通過 App 相關的自定義詞表(術語或短句)提供給 Siri,讓 Siri 可以識別出和 App 相關的獨特信息可以優化使用體驗。這樣的關鍵詞表分為兩類:

  • 和 App 相關的關鍵詞表(App-specific vocabulary);
  • 和某個用戶相關的關鍵詞表(User-specific vocabulary);

App-specific vocabulary

提供 App-specific vocabulary 的方式是在主 App 內集成 App vocabulary plist 文件。

在主 App(注意不是 Extension) 的 Bundle 中創建 AppIntentVocabulary.plist 文件來幫助 Siri 了解和 App 有關的術語,甚至可以提供該術語的發音信息和使用例句。

AppIntentVocabulary.plist 文件是支持本地化的,可以為App 的每種語言版本提供不同的詞表信息。

這個 plist 文件的根字典可以包含兩個 Key:

Key類型簡介ParameterVocabularies字典列表(必填)符合 App 目前支持的 Intents 某個特定屬性的術語列表IntentPhrases字典列表(選填)在 Siri 的引導中展示並提供給 Siri 做深度學習的短句,。

ParameterVocabularies

ParameterVocabularies 列表中的字典可以包含兩個 Key:

Key類型簡介ParameterNames字元串列表(必填)術語可以應用於的 Intent 屬性,用<intent>.<property>的形式表示ParameterVocabulary字典列表(必填)術語的同義詞列表,包括發音和例句

ParameterNames 中目前只能為打車和健身類型的意圖設置 App 級別的關鍵詞表,支持如下屬性:

  • INRequestRideIntent.rideOptionName
  • INStartWorkoutIntent.workoutName
  • INPauseWorkoutIntent.workoutName
  • INResumeWorkoutIntent.workoutName
  • INEndWorkoutIntent.workoutName
  • INCancelWorkoutIntent.workoutName

ParameterVocabulary 列表中的字典包含兩個 Key:

  • VocabularyItemIdentifier:必填,自定義術語的標識。?當Siri 通過語音識別出當前的術語後,會把這個標識賦值給 ParameterNames 中的 Intent 屬性上,這個標識不會被用戶看到,並且在plist 的所有本地化版本中應該是一致的。
  • VocabularyItemSynonyms:一組同義詞的字典列表。?該字典可以包含三個 Key:
    • VocabularyItemPhrase: 用於 Siri 識別和展示的短語,如:iTunes;
    • VocabularyItemPronunciation: 在本地化語言中該短語的近似發音,Siri 會根據這個發音來識別短句。如:iTunes 對應的發音讀作 「eye toons」。除英語外,SiriKit 針對三種語言提供了發音的描述方法,分別是:zh_CN、zh_TW、zh_HK;
    • VocabularyItemExamples: 一個在常見使用場景中的例句列表。

IntentPhrases

IntentPhrase 列表中的每個字典都包含兩個 key:

Key類型簡介IntentName字元串(必填) 例句所對應的 Intent 類(6種)IntentExamples字元串列表(必填) 當前 Intent 語境中用戶可能的表達方式

以在呼呼打車中打車為例,IntentExamples 可能的表達方式有:

  • 「用呼呼打一輛跑車到林大北路」
  • 「幫我在呼呼上預訂一輛明早8點的卡車」
  • 「查找呼呼明天下午6點從公司回家的順風車」

AppIntentVocabulary.plist 示例

如下是一個支持 SiriKit 的健身應用中 AppIntentVocabulary.plist 的完整示例:

User-specific vocabulary

另一種向 Siri 提供自定義詞表的方式是在運行時由 App 提供一個用戶特定的、以OrderedSet類型返回的關鍵詞表,比如通訊錄中的收藏、最近聯繫人。

在提供自定義詞表時應注意以下幾點:

* 只提供必要的信息,比如 iOS 的通訊錄已經被 Siri 收錄,不需要重新提供;

* 數據變化的時及時更新;

* 適時的刪除這部分信息,如:當前用戶退出登錄時刪除當前用戶相關的聯繫人信息。

使用INVocabulary對象為一個獨立用戶註冊一個指定 Intent 類型的詞表。通過調用 SiritKit 提供的 API:- setVocabularyStrings:ofType:方法來實現。

以提供最近聯繫為例,代碼實現如下:

// SiriKitNSOrderedSet *tStrings = [self recentlyContacts];INVocabulary *voc = [INVocabulary sharedVocabulary];[voc setVocabularyStrings:tStrings ofType:INVocabularyStringTypeContactName];// -- SiriKit

對於註冊方法的使用有如下幾點提示:

  • 上述代碼需要編碼在主 App 中,而不是在 Intent Extensions;
  • INVocabulary 中的詞表只支持如下四種類型:
    • 聯繫人(Contacts framework 提供之外的)
    • 照片標籤
    • 相冊名稱
    • 健身運動名稱
  • 針對每種 Intent 類型只能保存一組詞表,下次調用會覆蓋當前詞表,因此要保證將詞表信息一次性的註冊進去;
  • 詞表的內容數量是有限的,盡量只註冊用戶收藏、最常用或者最近使用過的詞表信息。

許可權控制

和地理位置、通知一樣,使用 SiriKit 也需要請求系統許可權,並且在彈窗中解釋用戶的哪些信息可能被發送到 Siri。例如在 WWDC 2016 Session#217 中 UnicornPay 這個應用的彈窗:

如果第一次使用 SiriKit 時尚未授權,Siri 會引導到 App 的 Siri 許可權設置界面。

總結

到這裡你已經了解了利用 SiriKit 開發 App 和 Extensions 的全部過程和相關知識。

Siri 從問世開始,開發者們就一直在等待 API 開放,SiriKit 如今總算是「千呼萬喚始出來」。SiriKit 不僅為 App 帶來了人工智慧,同時 SiriKit 也為每個應用提供了新的系統級入口,用戶無需進入 App,也不需要任何點擊操作就可以完成想要的操作,消息發送、撥打視頻電話、轉賬、打車、健身變得更加即時方便。

當然,SiriKit 和所有首次開放的 API 一樣,目前仍然不夠成熟,有兩個方面需要提高:一個是更智能豐富的中文語意識別;二是由於 Siri 的輸入存在非常多的可能性,在實際應用的過程中會出現令人困惑,或者 API 調用結果不符合我們預期的情況。

無論如何,通過 WWDC 2016 可以看到,iOS,macOS,watchOS 和 tvOS 這四個產品線上的布局已經完成,蘋果生態整合又前進了一步。各個平台的交互體驗、一致性、安全性都得到了進一步的提升。正如 SiriKit 的開放一樣,蘋果開發者們面臨新的挑戰的同時,也應該看到許多新的機會。隨著 Siri 的發展,用戶與智能設備的交互方式不僅僅停留在視覺和觸覺,越來越多的人會開始使用 Siri,感受 Siri 給這個世界帶來的不同。

為表述方便,本文中主要以發送消息類型的意圖(Intent)為例進行介紹,發送或者接收付款、打車、健身等類型的 SiriKit App 開發方式與之基本相同,讀者可以繼續嘗試實現。

引用

  • WWDC 2016 中有兩個 Session 介紹了 SiriKit:
    • Session#217
    • Session#225
  • 內容基本相同,217 更偏重於 SiriKit 的使用原理,最後一部分還有一些用戶交互設計的 Tips,225 偏重於實現,增加了 Demo 開發代碼的演示。
  • Apple 的官方文檔:SiriKit Programming Guide。

推薦閱讀:

垃圾郵件和 Bot 的前世今生
想不到 原來你是這樣的SIRI
上海話siri的效果如何?
Siri 如果支持在 Mac 桌面端使用,可以做哪些事情?

TAG:iOS | Siri |