版本記錄
版本號 | 時間 |
---|---|
V1.0 | 2018.09.12 |
前言
大家都知道隨著人工智能的發(fā)展,會掀起來另外一個工業(yè)革命哑蔫,而語音識別就是人工智能的初始階段钉寝,但是每個公司做的都不一樣,涉及到一系列的語音的采集和算法實現(xiàn)闸迷,蘋果的Siri就是業(yè)界語音識別的代表性的產(chǎn)品嵌纲。接下來的幾篇我們就詳細(xì)解析一下SiriKit這個框架。感興趣的可以看下面幾篇文章腥沽。
1. SiriKit框架詳細(xì)解析(一)—— 基本概覽(一)
2. SiriKit框架詳細(xì)解析(二)—— 請求授權(quán)使用SiriKit和INPreferences類(一)
3. SiriKit框架詳細(xì)解析(三)—— 創(chuàng)建Intents App擴(kuò)展(一)
4. SiriKit框架詳細(xì)解析(四)—— 構(gòu)建代碼以支持App擴(kuò)展和將意圖調(diào)度到處理對象(一)
5. SiriKit框架詳細(xì)解析(五) —— 編程指南之Intents和Intents UI擴(kuò)展(一)
Confirming a Request - 確認(rèn)請求
在令人滿意地解析了意圖的所有參數(shù)之后逮走,要求處理程序確認(rèn)意圖的細(xì)節(jié)并提出響應(yīng)。當(dāng)所有參數(shù)都已成功解析或不需要繼續(xù)進(jìn)行時今阳,所有參數(shù)的滿意解析都會發(fā)生师溅。在確認(rèn)期間,您可以對所有意圖參數(shù)執(zhí)行其他驗證盾舌,確保您可以使用該信息來執(zhí)行所請求的服務(wù)墓臭。
不需要在處理程序中實現(xiàn)確認(rèn)方法,但強(qiáng)烈建議使用妖谴。 Siri始終提示用戶確認(rèn)重要請求起便,尤其是那些不可撤銷或涉及金融交易的請求。 Siri可能會或可能不會在其他情況下提示用戶窖维。無論哪種方式,實施確認(rèn)方法都是確保您能夠提供響應(yīng)的好方法妙痹。
Listing 3-2
顯示了一個用于開始鍛煉的簡單確認(rèn)方法铸史。確認(rèn)方法的主要工作是使用響應(yīng)對象執(zhí)行提供的完成塊。此示例創(chuàng)建一個響應(yīng)對象怯伊,指示可以成功啟動鍛煉琳轿。如果要執(zhí)行任何其他驗證,可以使用此方法執(zhí)行此操作耿芹。
// Listing 3-2 Confirming the start of a workout
// OC
- (void)confirmStartWorkout:(INStartWorkoutIntent *)startWorkoutIntent
completion:(void (^)(INStartWorkoutIntentResponse * _Nonnull))completion
{
NSUserActivity *activity = [[NSUserActivity alloc]
initWithActivityType:@"startWorkoutActivityType"];
INStartWorkoutIntentResponse* response = [[INStartWorkoutIntentResponse alloc] initWithCode:INStartWorkoutIntentResponseCodeSuccess userActivity:activity];
// Perform any final validation.
completion(response);
}
//Swift
func confirmStartWorkout(startWorkout intent: INStartWorkoutIntent,
completion: (INStartWorkoutIntentResponse) -> Void)
{
let activity = NSUserActivity(activityType: "startWorkoutActivityType")
let response = INStartWorkoutIntentResponse(code: .success, userActivity: activity)
// Perform any final validation.
completion(response)
}
有關(guān)為每個intent
創(chuàng)建的響應(yīng)對象的信息崭篡,請參閱Intents Domains
。
Handling a Request - 處理請求
處理意圖的最后階段是執(zhí)行與該意圖相關(guān)聯(lián)的操作吧秕。處理程序?qū)ο蟮?code>handle方法有兩個職責(zé):
- 執(zhí)行與意圖相關(guān)的任務(wù)琉闪。
- 返回一個響應(yīng)對象,其中包含有關(guān)您的應(yīng)用程序執(zhí)行了什么砸彬。
處理任務(wù)時颠毙,請連接到您的服務(wù)并執(zhí)行相關(guān)任務(wù)斯入。執(zhí)行任務(wù)的實施細(xì)節(jié)完全由您負(fù)責(zé)。例如蛀蜜,乘車預(yù)訂服務(wù)將連接到公司的Web服務(wù)器以發(fā)出乘車請求并返回結(jié)果刻两。
除了執(zhí)行任務(wù)外,還要創(chuàng)建一個包含所執(zhí)行操作詳細(xì)信息的響應(yīng)對象滴某。您放入響應(yīng)對象的信息因每個意圖而異磅摹,某些響應(yīng)對象可能需要比其他更多的信息。您還應(yīng)該為NSUserActivity
對象提供應(yīng)用程序可能需要繼續(xù)執(zhí)行任務(wù)的任何其他詳細(xì)信息霎奢。用戶可能會選擇立即啟動您的應(yīng)用以獲取更多詳細(xì)信息户誓。如果發(fā)生這種情況,用戶活動對象應(yīng)包含使用任務(wù)詳細(xì)信息配置應(yīng)用程序界面所需的任何信息椰憋。
Listing 3-3
顯示了一個handle方法厅克,用于報告新啟動的鍛煉的狀態(tài)。在此示例中橙依,處理程序調(diào)用自定義方法证舟,該方法在返回對Siri的響應(yīng)之前通知應(yīng)用程序啟動指定的鍛煉。
// Listing 3-3 Handling the start of a workout
// OC
- (void)handleStartWorkout:(INStartWorkoutIntent *)startWorkoutIntent
completion:(void (^) (INStartWorkoutIntentResponse * _Nonnull))completion
{
NSUserActivity *activity = [[NSUserActivity alloc] initWithActivityType:@"startWorkoutActivityType"];
INStartWorkoutIntentResponse* response = [[INStartWorkoutIntentResponse alloc] initWithCode:INStartWorkoutIntentResponseCodeSuccess userActivity:activity];
// Do the work…
[self startWorkoutWithName:startWorkoutIntent.workoutName];
completion(response);
}
//Swift
func handleStartWorkout(startWorkout intent: INStartWorkoutIntent,
completion: (INStartWorkoutIntentResponse) -> Void)
{
let activity = NSUserActivity(activityType: "startWorkoutActivityType")
let response = INStartWorkoutIntentResponse(code: .success, userActivity: activity)
// Do the work…
self.startWorkout(startWorkoutIntent.workoutName!)
completion(response)
}
您在Intents擴(kuò)展中所做的更改也應(yīng)反映在iOS應(yīng)用的界面中窗骑。 作為處理任務(wù)的一部分女责,您的擴(kuò)展程序應(yīng)該為您的iOS應(yīng)用程序提供任何所需的數(shù)據(jù)。 即使您可以為INInteraction
對象提供intent和響應(yīng)的詳細(xì)信息创译,但在所有情況下抵知,用戶活動對象都不會傳遞到您的應(yīng)用程序。 例如软族,用戶可以在不使用Handoff
的情況下啟動應(yīng)用程序刷喜。 為確保您的應(yīng)用是最新的,您的擴(kuò)展程序可以將任何更新的文件放在您的應(yīng)用可訪問的共享組容器中立砸。 然后掖疮,您的應(yīng)用可以使用后臺應(yīng)用刷新機(jī)會來獲取任何更改并自行更新。
有關(guān)為每個intent創(chuàng)建的響應(yīng)對象的信息颗祝,請參閱Intents Domains
浊闪。
Specifying Custom Vocabulary - 指定自定義詞匯表
擁有自定義詞匯表的應(yīng)用程序可以告知Siri正確使用該詞匯表。 自定義詞匯是指Siri可能無法理解的任何術(shù)語螺戳。 例如搁宾,將特定車輛類型稱為“Vroom”的乘車預(yù)訂應(yīng)用程序可以為Siri定義該術(shù)語并提供用戶如何使用它的示例。 定義應(yīng)用程序的詞匯表可為Siri提供有關(guān)理解與應(yīng)用程序相關(guān)的用戶命令的提示倔幼,并有助于改善整體用戶體驗盖腿。
有兩種方法可以定義應(yīng)用程序的自定義詞匯表:
- 要注冊特定于單個用戶的術(shù)語,請使用
INVocabulary
對象凤藏。 - 要注冊應(yīng)用程序的所有用戶共有的術(shù)語奸忽,請將
AppIntentVocabulary.plist
文件添加到iOS應(yīng)用程序堕伪。
重要:Siri將自定義詞匯表視為提示,盡可能多地結(jié)合您的自定義術(shù)語栗菜。 但是欠雌,自定義術(shù)語的空間有限,因此請務(wù)必僅注冊其使用可能會造成混淆的術(shù)語疙筹,并保持注冊術(shù)語的總數(shù)盡可能小富俄。
1. Registering User-Specific Vocabulary Terms - 注冊用戶特定詞匯術(shù)語
使用共享的INVocabulary
對象來注冊特定于單個用戶的詞匯表。用戶特定術(shù)語必須屬于以下類別之一:
- 聯(lián)系人姓名(僅當(dāng)他們不是由Contacts框架管理時)
- 照片標(biāo)簽
- 相冊名稱
- 鍛煉名稱
選擇要注冊的詞匯表時而咆,請選擇不熟悉您的應(yīng)用程序的人可能會誤解的詞匯霍比。例如,消息傳遞應(yīng)用程序可能會從用戶的收藏夾列表中注冊屏幕名稱暴备。不要注冊易于理解的術(shù)語悠瞬,例如“我的相冊”或“我的鍛煉”。相反涯捻,請關(guān)注其字面含義與應(yīng)用程序?qū)@些術(shù)語的使用不同的術(shù)語浅妆。
您可以使用setVocabularyStrings:ofType:
方法為每個類別注冊術(shù)語集。注冊一組新術(shù)語將替換該類別的先前術(shù)語障癌,因此請在每次調(diào)用該方法時包含所需的所有術(shù)語凌外。不要包括所有可用的術(shù)語。相反涛浙,請關(guān)注與用戶收藏夾相關(guān)的術(shù)語康辑,頻繁使用的術(shù)語或最近使用的術(shù)語。最重要的術(shù)語應(yīng)始終位于您創(chuàng)建的NSOrderedSet
對象中轿亮。
Listing 4-1
顯示了一個注冊一組自定義訓(xùn)練的示例疮薇。 該應(yīng)用程序根據(jù)最后一次使用鍛煉名稱對鍛煉名稱進(jìn)行分類,將最近使用的鍛煉放在有序集合中我注。 通常惦辛,您從應(yīng)用程序注冊特定于用戶的術(shù)語,而不是從Intents擴(kuò)展注冊仓手。
//Listing 4-1 Registering user-specific vocabulary
//OC
NSOrderedSet* workoutNames = [self sortedWorkoutNames];
INVocabulary* vocabulary = [INVocabulary sharedVocabulary];
[vocabulary setVocabularyStrings:workoutNames ofType:INVocabularyStringTypeWorkoutActivityName];
//Swift
let workoutNames = self.sortedWorkoutNames()
let vocabulary = INVocabulary.shared()
vocabulary.setVocabularyStrings(workoutNames, of:.workoutActivityName)
注冊一組術(shù)語并不能保證Siri稍后會認(rèn)可它們。 Siri會將您提供的任何條款視為提示玻淑,并在可能的情況下使用它們嗽冒。 因此,重點關(guān)注應(yīng)用程序?qū)δ膽?yīng)用程序以及特定用戶和實際使用的用途所特有的術(shù)語补履。 不要包含用戶在與Siri交談時永遠(yuǎn)不會使用的通用術(shù)語或術(shù)語添坊。
有關(guān)注冊用戶特定詞匯表術(shù)語的其他信息,請參閱INVocabulary Class Reference
箫锤。
2. Creating the Global Vocabulary File - 創(chuàng)建全局詞匯文件
使用全局詞匯表文件來注冊應(yīng)用程序的所有用戶共有的詞匯表贬蛙。 全局術(shù)語必須屬于以下類別之一:
- 乘車選擇
- 鍛煉名稱
全局詞匯表文件是名為AppIntentVocabulary.plist
的屬性列表文件雨女。 將此文件放在與應(yīng)用程序的基本開發(fā)語言對應(yīng)的.lproj
目錄中。 在應(yīng)用程序的特定于語言的項目(.lproj)
目錄中包含本地化版本阳准。 在Xcode中氛堕,您可以從“文件”檢查器自動創(chuàng)建本地化版本。
To create the global vocabulary file - 創(chuàng)建全局詞匯表文件
- 1) 選擇
New > File
野蝇。 - 2) 在
iOS > Resource
中讼稚,選擇屬性列表文件類型。 - 3) 點擊
Next
绕沈。 - 4) 將文件名設(shè)置為
AppIntentVocabulary.plist
锐想。 - 5) 單擊
Create
- 6) 在項目中選擇
AppIntentVocabulary.plist
文件。 - 7) 在Root元素下添加兩個鍵乍狐。
- 將第一個鍵的名稱設(shè)置為
ParameterVocabularyies
赠摇。 - 將第二個鍵的名稱設(shè)置為
IntentPhrases
。
- 將第一個鍵的名稱設(shè)置為
全局詞匯表文件在根級別包含兩個鍵:
-
ParameterVocabularyies
鍵定義應(yīng)用程序的自定義術(shù)語及其應(yīng)用的intent參數(shù)浅蚪。 -
IntentPhrases
鍵包含包含您的自定義術(shù)語的示例短語藕帜。
對于每個自定義術(shù)語,請指定該術(shù)語適用的術(shù)語和intent屬性掘鄙。單個術(shù)語可以與多個意圖相關(guān)聯(lián)耘戚。例如,自定義鍛煉名稱可以同等地應(yīng)用于所有其他與鍛煉相關(guān)的意圖類別操漠。除了術(shù)語和意圖信息之外收津,還可以指定SiriKit的標(biāo)識符字符串以放置在intent對象中。在解決過程中浊伙,您可以將該標(biāo)識符字符串解析為適當(dāng)?shù)腻憻挕?/p>
重要:在開發(fā)過程中撞秋,Xcode會將您的全局詞匯轉(zhuǎn)發(fā)給Siri,但會限制該詞匯表對您的開發(fā)設(shè)備的可用性嚣鄙。 攝取詞匯數(shù)據(jù)不是即時的吻贿,因此在測試任何自定義詞匯表之前,您可能需要等待一兩分鐘哑子。
有關(guān)全局詞匯表文件的結(jié)構(gòu)和鍵的詳細(xì)信息舅列,請參閱App Vocabulary File Format
。
Providing a Custom Interface - 提供自定義界面
Siri和Maps應(yīng)用程序顯示Intents
擴(kuò)展程序提供的信息卧蜓,但您可以使用Intents UI
擴(kuò)展程序自定義部分顯示內(nèi)容帐要。Intents UI
擴(kuò)展的目的是自定義Siri或Maps界面,以便用戶知道您的應(yīng)用程序正在提供響應(yīng)弥奸。例如榨惠,您可以添加與您的brand
相關(guān)的可視元素,或者提供與請求相關(guān)但不是標(biāo)準(zhǔn)界面的其他信息。
Intents UI
擴(kuò)展包含一個視圖控制器赠橙,您可以使用該視圖控制器填充與應(yīng)用程序響應(yīng)相關(guān)的信息耽装。您可以顯示應(yīng)用程序支持的任何或所有意圖的自定義信息。當(dāng)顯示對支持的意圖的響應(yīng)時期揪,Siri和Maps將您的Intents UI擴(kuò)展中的視圖控制器集成到它們顯示的界面中掉奄。使用傳遞給視圖控制器的響應(yīng)數(shù)據(jù)來配置任何視圖的內(nèi)容并確定要顯示的內(nèi)容。您可以顯示與您的品牌相關(guān)或?qū)τ脩粲杏玫娜魏涡畔⒑嵴臁D赡軣o法展示廣告挥萌。
您可以提供Intents UI擴(kuò)展,以支持與預(yù)訂枉侧,消息引瀑,付款和健身相關(guān)的意圖。有關(guān)如何使用Intents UI
擴(kuò)展的一些示例包括:
- Ride booking - 乘車預(yù)訂榨馁。顯示其他騎行細(xì)節(jié)和品牌憨栽。
- Messages - 消息。使用您的品牌顏色和樣式顯示消息內(nèi)容翼虫。
- Payments - 付款屑柔。顯示品牌或其他與付款相關(guān)的信息。
- Fitness - 健身珍剑。顯示自定義鍛煉信息掸宛。
Intents UI
擴(kuò)展可能支持多個意圖,但所有這些意圖共享相同的視圖控制器招拙。 您的視圖控制器會根據(jù)當(dāng)前意圖和顯示環(huán)境接收足夠的信息來自行配置唧瘾。 大多數(shù)意圖由Siri顯示,但乘坐預(yù)訂意圖通常由Maps
應(yīng)用程序顯示别凤。
1. Configuring Your Xcode Project - 配置Xcode項目
要自定義Siri界面饰序,請在iOS應(yīng)用程序中添加Intents UI
擴(kuò)展。 您可以在創(chuàng)建Intents擴(kuò)展時添加此擴(kuò)展规哪,也可以稍后將其添加到項目中求豫。
To add a new Intents UI extension to your app - 向您的應(yīng)用添加新的Intents UI擴(kuò)展
- 1) 在Xcode中打開現(xiàn)有的iOS應(yīng)用程序項目。
- 2) 選擇
File > New > Target
诉稍。 - 3) 從
iOS Application Extension
組中選擇Intents UI
擴(kuò)展蝠嘉。 - 4) 點擊
Next
。 - 5) 指定擴(kuò)展名稱并配置語言和其他選項杯巨。
- 6) 單擊
Finish
是晨。
Xcode提供的Intents UI
擴(kuò)展模板包含一個帶有單個視圖控制器的故事板。 Siri和Maps始終在故事板文件中加載并顯示初始視圖控制器舔箭,因此請使用您要顯示的內(nèi)容配置該視圖控制器。 如果要為每個intent顯示不同的視圖集,請創(chuàng)建子視圖控制器并在運行時將它們嵌入到初始視圖控制器中层扶。
Intents UI
擴(kuò)展的Info.plist
文件告訴Siri您的擴(kuò)展支持哪些意圖箫章。 表5-1列出了擴(kuò)展的Info.plist
文件中NSExtension
鍵字典中必須包含的鍵。 您可以在NSExtensionAttributes
鍵的字典中指定支持的意圖镜会。
Table 5-1 Keys for the Info.plist file of an Intents UI extension
Key | Description |
---|---|
NSExtensionAttributes |
與此鍵關(guān)聯(lián)的字典必須包含IntentsSupported 鍵檬寂,其值為字符串?dāng)?shù)組。 每個字符串的值是擴(kuò)展支持的intent類的名稱戳表。 |
NSExtensionMainStoryboard |
此鍵的值是包含擴(kuò)展程序視圖控制器的Storyboard 文件的名稱桶至。 如果您希望系統(tǒng)以編程方式創(chuàng)建視圖控制器,則可以將NSExtensionPrincipalClass 鍵替換為此鍵匾旭。 |
NSExtensionPointIdentifier |
此鍵的值必須是字符串com.apple.intents-ui-service
|
To specify the intents that your custom interface supports - 指定自定義接口支持的意圖
- 1) 在Xcode中镣屹,選擇
Intents
擴(kuò)展的Info.plist
文件。 - 2) 展開
NSExtension
和NSExtensionAttributes
鍵以查看IntentsSupported
鍵价涝。 - 3) 在
IntentsSupported
鍵中女蜈,為您支持的每個意圖添加項目。 每個項的類型必須是String
色瘩,并且值必須是intent的類名伪窖。
2. Implementing Your View Controller - 實現(xiàn)View Controller
Intents UI
擴(kuò)展的故事板的初始視圖控制器負(fù)責(zé)顯示您的內(nèi)容。在顯示響應(yīng)之前居兆,Siri或Maps應(yīng)用程序加載該視圖控制器并調(diào)用其configureWithInteraction:context:completion:
方法覆山。使用該方法中的交互對象配置視圖控制器的內(nèi)容并使其準(zhǔn)備好顯示在屏幕上。使用context參數(shù)根據(jù)Siri或Maps界面的需要調(diào)整內(nèi)容的顯示泥栖。
在屏幕上簇宽,視圖控制器仍然是前臺界面的一部分,直到用戶移除Siri或Maps界面聊倔。您可以根據(jù)需要使用計時器或其他編程方式更新視圖控制器的界面晦毙,并且視圖控制器在加載,顯示和隱藏時參與普通視圖控制器進(jìn)程耙蔑。但是见妒,視圖控制器在屏幕上時不會接收觸摸事件和其他響應(yīng)者鏈?zhǔn)录⑶夷鸁o法添加手勢識別器或嘗試以其他方式攔截事件甸陌。因此须揣,您不應(yīng)該包含需要用戶交互的控件或視圖。
圖5-1顯示了Intents UI
擴(kuò)展及其視圖控制器的生命周期钱豁。系統(tǒng)創(chuàng)建視圖控制器并調(diào)用其configureWithInteraction:context:completion:
方法耻卡,向其傳遞配置界面所需的交互對象。配置完成后牲尺,您的視圖控制器將顯示在屏幕上卵酪,其中包含Siri或地圖的其他內(nèi)容幌蚊。在屏幕上,您的視圖控制器可以使用計時器和其他編程方式運行動畫并更新自身溃卡,但它不會接收觸摸事件或響應(yīng)者鏈?zhǔn)录?/p>
當(dāng)用戶關(guān)閉Siri或Maps界面時溢豆,系統(tǒng)會釋放對視圖控制器和Intents UI
擴(kuò)展的引用。視圖控制器應(yīng)僅用于顯示信息瘸羡。當(dāng)視圖控制器移出屏幕時漩仙,請勿嘗試保存數(shù)據(jù)或與應(yīng)用程序通信。
以下是為Intents UI
擴(kuò)展實現(xiàn)視圖控制器的一些提示:
Incorporate your brand into your interface - 將您的brand融入您的界面犹赖。使用應(yīng)用程序的顏色队他,圖像和其他設(shè)計元素是增加熟悉度并傳達(dá)應(yīng)用程序存在的好方法。
Use child view controllers to switch between different types of content - 使用子視圖控制器在不同類型的內(nèi)容之間切換峻村。您的
Intents UI
擴(kuò)展只有一個主視圖控制器麸折。如果為不同的意圖顯示不同的內(nèi)容,請使用子視圖控制器來管理與該意圖相關(guān)的視圖雀哨。在configureWithInteraction:context:completion:
方法中磕谅,根據(jù)提供的intent
對象安裝子視圖控制器。Configure any animated content to run only when your view controller is visible - 配置任何動畫內(nèi)容僅在視圖控制器可見時運行雾棺。等到視圖控制器的
viewDidAppear:
方法被調(diào)用以啟動動畫膊夹。在視圖控制器的viewWillDisappear:
方法中停止動畫。Configure your view controller’s view as quickly as possible so that Siri can display it - 盡快配置視圖控制器的視圖捌浩,以便Siri可以顯示它放刨。您的視圖控制器可能不會在屏幕上顯示很長時間,因此請為您的大部分配置使用本地資源和提供的
INInteraction
對象尸饺。如果需要從服務(wù)器獲取更多信息进统,請始終異步執(zhí)行此操作并稍后更新您的界面。Do not include advertising in your interface - 不要在界面中添加廣告浪听。您可以包含與用戶相關(guān)的品牌和信息螟碎,但禁止廣告。
有關(guān)配置視圖控制器的更多信息迹栓,請參閱NUIHostedViewControlling Protocol Reference
掉分。
3. Replacing the Default Interface - 替換默認(rèn)界面
對于乘車預(yù)訂和消息意圖,您可以隱藏系統(tǒng)提供的默認(rèn)內(nèi)容(如果它與您提供的內(nèi)容沖突)克伊。 對于消息意圖酥郭,Siri顯示消息內(nèi)容和收件人。 對于乘車預(yù)訂意圖愿吹,Siri和Maps應(yīng)用程序會顯示一個顯示用戶位置的地圖不从。 如果為自己的界面提供相同的信息,請使用INUIHostedViewSiriProviding
協(xié)議的屬性來禁止顯示系統(tǒng)界面犁跪。
有關(guān)抑制默認(rèn)地圖和消息信息的詳細(xì)信息椿息,請參閱INUIHostedViewSiriProviding Protocol Reference
歹袁。
后記
本篇主要講述了編程指南之確認(rèn)和處理請求、指定自定義詞匯表和界面寝优,感興趣的給個贊或者關(guān)注~~~