版本記錄
版本號(hào) | 時(shí)間 |
---|---|
V1.0 | 2018.12.06 星期四 |
前言
大家都知道隨著人工智能的發(fā)展纹份,會(huì)掀起來另外一個(gè)工業(yè)革命,而語(yǔ)音識(shí)別就是人工智能的初始階段棱貌,但是每個(gè)公司做的都不一樣锣披,涉及到一系列的語(yǔ)音的采集和算法實(shí)現(xiàn)原环,蘋果的Siri就是業(yè)界語(yǔ)音識(shí)別的代表性的產(chǎn)品挠唆。接下來的幾篇我們就詳細(xì)解析一下SiriKit這個(gè)框架。感興趣的可以看下面幾篇文章嘱吗。
1. SiriKit框架詳細(xì)解析(一)—— 基本概覽(一)
2. SiriKit框架詳細(xì)解析(二)—— 請(qǐng)求授權(quán)使用SiriKit和INPreferences類(一)
3. SiriKit框架詳細(xì)解析(三)—— 創(chuàng)建Intents App擴(kuò)展(一)
4. SiriKit框架詳細(xì)解析(四)—— 構(gòu)建代碼以支持App擴(kuò)展和將意圖調(diào)度到處理對(duì)象(一)
5. SiriKit框架詳細(xì)解析(五) —— 編程指南之Intents和Intents UI擴(kuò)展(一)
6. SiriKit框架詳細(xì)解析(六) —— 編程指南之確認(rèn)和處理請(qǐng)求玄组、指定自定義詞匯表和界面(一)
7. SiriKit框架詳細(xì)解析(七) —— 構(gòu)建Siri Shortcuts簡(jiǎn)單示例(一)
Publishing Articles with Siri
接下來,您希望添加發(fā)布直接從Siri編寫的文章的功能谒麦。 這里的最大區(qū)別在于俄讹,不是Siri打開你的應(yīng)用程序,一切都將直接來自Siri UI
绕德。
對(duì)于此快捷方式患膛,您將創(chuàng)建一個(gè)自定義Intent
來定義Siri,您的用戶和您的應(yīng)用之間的來回耻蛇。
1. Defining a Custom Writing Intent
在項(xiàng)目導(dǎo)航器中踪蹬,找到ArticleKit
文件夾并單擊它以突出顯示它。
然后臣咖,按Command + N
創(chuàng)建一個(gè)新文件跃捣。
在過濾器搜索框中,鍵入Intent
夺蛇,您將看到SiriKit Intent Definition File
疚漆。
單擊Next
,然后將文件命名為ArticleIntents.intentdefinition
刁赦。
現(xiàn)在是時(shí)候創(chuàng)建一個(gè)發(fā)布你寫的文章的intent
了娶聘。
轉(zhuǎn)到讀取No Intents
的部分的底部,然后單擊加號(hào)按鈕以添加新的intent
意圖甚脉。
將其命名為PostArticle
丸升,然后根據(jù)這些設(shè)置配置您的意圖(在圖片后面描述):
此屏幕用于配置發(fā)布intent
需要處理的信息。
Custom Intent
部分中的選項(xiàng)定義了它的意圖類型宦焦,并且可以影響Siri如何處理該操作发钝。 告訴Siri這是一個(gè)Post
類型動(dòng)作讓系統(tǒng)知道你在某處分享了一些內(nèi)容:
- 1) Category:
Post
- 2) Title:
Post Article
- 3) Description:
Post the last article
- 4) Default Image:
Select one of the existing images in the project
- 5) Confirmation:
Check this box since you want to ask the user to verify that they’re really ready to publish this article
Parameters
部分用于定義Title
和Subtitle
中使用的任何動(dòng)態(tài)屬性,您現(xiàn)在可以使用這些屬性波闹。
定義一個(gè)名為article
的參數(shù)酝豪,它是一個(gè)Custom
數(shù)據(jù)類型,一個(gè)是類型為String
的publishDate
精堕。
然后孵淘,在Shortcut Types
部分中,單擊加號(hào)按鈕以添加一個(gè)包含article
和publishDate
參數(shù)作為其參數(shù)的類型歹篓。
接下來瘫证,設(shè)置快捷方式的Title
和Subtitle
。
將標(biāo)題設(shè)置為Post “${article}”
和副標(biāo)題設(shè)置為on ${publishDate}
庄撮。 如果您不復(fù)制和粘貼背捌,請(qǐng)確保讓Xcode自動(dòng)完成article
和publishDate
。
最后洞斯,確保選中Supports background execution
毡庆,這樣您就不會(huì)被迫離開Siri UI
。
2. Setting Up Siri’s Responses
單擊Response
烙如,您可以定義Siri將如何響應(yīng)用戶么抗。
再次,配置您的響應(yīng)亚铁,如下所示:
在Properties
下蝇刀,您可以再次定義Siri所說的動(dòng)態(tài)部分。 添加title
徘溢,publishDate
和failureReason
的屬性吞琐;把它們都定義為字符串。
然后然爆,在Response Templates
下顽分,為failure
添加此模板:
Sorry, but I couldn't post your article. ${failureReason}
為成功添加以下模板
Your article "${title}" was successfully posted on ${publishDate}. Nice work!
3. Adding a Siri Extension
為了能夠在不啟動(dòng)應(yīng)用程序的情況下繼續(xù)使用Siri的UI,您需要使用可以管理交互的代碼創(chuàng)建Intents Extension
施蜜。
單擊左上角的項(xiàng)目文件卒蘸,然后找到允許您添加新目標(biāo)的加號(hào)。
現(xiàn)在翻默,找到Intents Extension
目標(biāo)缸沃;您可以在過濾搜索欄中搜索它。
然后修械,將您的意圖擴(kuò)展名為WritingIntents
趾牧,將Starting Point
設(shè)置為None
,并取消選中Include UI Extension
選項(xiàng)肯污。
最后翘单,單擊Finish
按鈕以創(chuàng)建擴(kuò)展吨枉。 構(gòu)建并運(yùn)行以確保事情仍然有效。
注意:當(dāng)Xcode提供激活
WritingIntents
方案時(shí)哄芜,單擊Cancel
貌亭。
沒什么新鮮的,但現(xiàn)在你已經(jīng)準(zhǔn)備好使用你的custom intents
了认臊!
在繼續(xù)之前圃庭,您需要做兩件快速的事情。
首先失晴,確保擴(kuò)展名中可以看到ArticleIntents.intentdefinition
剧腻。
打開文件,然后查看File inspector
涂屁。 確保其Target Membership
包括應(yīng)用程序书在,框架和擴(kuò)展。 此外拆又,請(qǐng)確保將應(yīng)用程序和擴(kuò)展目標(biāo)的代碼生成選項(xiàng)更改為No Generated Classes
蕊温,因?yàn)榇舜a應(yīng)存在于框架中。
接下來遏乔,您的擴(kuò)展程序和主應(yīng)用程序需要共享一個(gè)應(yīng)用程序組义矛。 由于文章保存到磁盤并從磁盤加載,因此這是兩個(gè)目標(biāo)在文件系統(tǒng)上共享同一區(qū)域的唯一方法盟萨。
單擊Project
導(dǎo)航器中的項(xiàng)目文件凉翻,確保選擇了TheBurgeoningWriter
并轉(zhuǎn)到Capabilities
選項(xiàng)卡。
將App Groups
功能切換為ON
捻激,并命名組為group.<your-bundle-id>
制轰。
接下來,選擇WritingIntents
擴(kuò)展并執(zhí)行相同的操作胞谭。 這一次垃杖,該組應(yīng)該存在,因此您可以只檢查該框丈屹。
最后调俘,打開ArticleManager.swift
并找到groupIdentifier
的聲明。 更改其值以匹配新定義的應(yīng)用程序組名稱旺垒。
注意:此更改后彩库,您輸入的先前文章將不再顯示在應(yīng)用中。 這是預(yù)期的先蒋,因?yàn)樗鼈兇鎯?chǔ)在文件系統(tǒng)中的不同位置骇钦。
4. Donating Post Article Intents
現(xiàn)在您已經(jīng)定義了發(fā)布文章的intent
,現(xiàn)在是時(shí)候在適當(dāng)?shù)臅r(shí)候創(chuàng)建和提交一個(gè)竞漾。
再一次眯搭,前往Article.swift
窥翩,這樣你就可以添加一種方法來為新文章生成“post”
的intents
。
在newArticleShortcut(thumbnail :)
的定義下方鳞仙,添加以下方法定義:
public func donatePublishIntent() {
}
此方法一次創(chuàng)建并提供intent
寇蚊,因?yàn)槟恍枰幚硐蛞晥D控制器添加intents
。
現(xiàn)在繁扎,創(chuàng)建intent
對(duì)象并分配article and publish date
:
let intent = PostArticleIntent()
intent.article = INObject(identifier: self.title, display: self.title)
intent.publishDate = formattedDate()
當(dāng)使用自定義intent
時(shí)幔荒,您最終提交給系統(tǒng)的事情就是這樣的交互糊闽。
最后梳玫,通過在交互上調(diào)用donate(_ :)
來提交:
interaction.donate(completion: nil)
在這里,您將提交您的互動(dòng)右犹,而不必?fù)?dān)心completion
塊提澎。 當(dāng)然,您可以將錯(cuò)誤處理或其他任何內(nèi)容添加到此完成塊中念链。
您必須完成最后一次“secret handshake”
步驟:您必須告訴iOS確切的應(yīng)用程序支持的intents
盼忌。 為此,請(qǐng)單擊Project
導(dǎo)航器中的項(xiàng)目文件掂墓。 選擇WritingIntents
目標(biāo)谦纱,然后單擊Info
選項(xiàng)卡。 按住Option
鍵并單擊NSExtension
鍵旁邊的顯示三角形以打開整個(gè)鍵君编。 將鼠標(biāo)懸停在IntentsSupported
上以顯示加號(hào)按鈕并單擊一次跨嘉。 將新添加的項(xiàng)的值設(shè)置為PostArticleIntent
。
這就是向系統(tǒng)提交intent-based
的快捷方式的全部?jī)?nèi)容吃嘿。
現(xiàn)在您已經(jīng)定義了方法祠乃,轉(zhuǎn)到NewArticleViewController.swift
并找到saveWasTapped()
。 由于您希望系統(tǒng)提示用戶發(fā)布他們以后保存的文章兑燥,因此您可以在這里實(shí)現(xiàn)亮瓷。
添加此行以在該方法中的注釋下方提交intent
:
article.donatePublishIntent()
現(xiàn)在您正在提交,構(gòu)建和運(yùn)行應(yīng)用程序降瞳。 然后嘱支,創(chuàng)建并保存新文章。 完成后挣饥,轉(zhuǎn)到Spotlight
搜索斗塘,您應(yīng)該會(huì)看到一個(gè)類似于此的新提交。
5. Handling Intents-Based Shortcuts
像以前一樣亮靴,您現(xiàn)在必須考慮在用戶使用它時(shí)處理此快捷方式馍盟。
這一次,您創(chuàng)建的擴(kuò)展將負(fù)責(zé)處理事物茧吊。
首先贞岭,在名為PostArticleIntentHandler.swift
的WritingIntents
文件夾中添加一個(gè)新的Swift
文件八毯。
用以下內(nèi)容替換import Foundation
:
import UIKit
import ArticleKit
class PostArticleIntentHandler: NSObject, PostArticleIntentHandling {
func confirm(intent: PostArticleIntent,
completion: @escaping (PostArticleIntentResponse) -> Void) {
}
func handle(intent: PostArticleIntent,
completion: @escaping (PostArticleIntentResponse) -> Void) {
}
}
在這里,您將創(chuàng)建一個(gè)類來處理涉及您的發(fā)布article intent
的交互瞄桨。
符合PostArticleIntentHandling
協(xié)議意味著您需要實(shí)現(xiàn)一個(gè)涉及確認(rèn)步驟的方法和一個(gè)用戶在確認(rèn)后處理意圖的方法话速。
接下來,添加以下代碼到confirm(intent:completion:)
:
completion(PostArticleIntentResponse(code: PostArticleIntentResponseCode.ready,
userActivity: nil))
這表示如果用戶點(diǎn)擊確認(rèn)芯侥,則擴(kuò)展已準(zhǔn)備好接受意圖泊交。
接下來,您將實(shí)現(xiàn)handle(intent:completion:)
柱查。
這是真正的選擇發(fā)揮作用的地方廓俭。 由于用戶試圖發(fā)布文章,因此只應(yīng)在成功消息的情況下響應(yīng)唉工。
首先研乒,在找不到他們選擇的文章時(shí)添加此保護(hù)聲明:
guard let title = intent.article?.identifier,
let article = ArticleManager.findArticle(with: title) else {
completion(PostArticleIntentResponse
.failure(failureReason: "Your article was not found."))
return
}
這會(huì)使用failure
意圖響應(yīng)調(diào)用completion
塊。 它唯一的參數(shù)叫做failureReason
淋硝,因?yàn)槟阒皠?chuàng)建的失敗響應(yīng)模板在模板中有failReason
變量雹熬。
接下來,為本文已發(fā)布時(shí)添加一個(gè)guard
:
guard !article.published else {
completion(PostArticleIntentResponse
.failure(failureReason: "This article has already been published."))
return
}
最后谣膳,對(duì)于成功情況竿报,您將發(fā)布文章并使用成功響應(yīng)調(diào)用completion
塊。 這包括文章的標(biāo)題和發(fā)布日期:
ArticleManager.publish(article)
completion(PostArticleIntentResponse
.success(title: article.title, publishDate: article.formattedDate()))
現(xiàn)在您已經(jīng)設(shè)置了intent
處理程序继谚,您必須確保它已被使用烈菌。
打開IntentHandler.swift
并用以下內(nèi)容替換現(xiàn)有的handler(for:)
,告訴系統(tǒng)使用剛寫的處理程序:
override func handler(for intent: INIntent) -> Any {
return PostArticleIntentHandler()
}
接下來犬庇,打開AppDelegate.swift
并找到application(_:continue:restorationHandler:)
僧界。
您可能沒有想到的是,即使您有自己的處理程序來處理此快捷方式臭挽,仍會(huì)調(diào)用應(yīng)用程序委托中的continue user activity callback
捂襟。
要阻止該方法將用戶從Siri
中刪除并進(jìn)入new article view
,請(qǐng)?zhí)砑右韵?code>guard:
guard userActivity.interaction == nil else {
ArticleManager.loadArticles()
rootVC.viewWillAppear(false)
return false
}
如果活動(dòng)附加了交互欢峰,則表示其為“publish”
快捷方式葬荷,您需要加載文章并確保重新加載feed view controller
。
構(gòu)建并運(yùn)行纽帖,然后編寫新文章以提交其中一個(gè)快捷方式宠漩。
注意:您可以放心地忽略有關(guān)鏈接到
dylib
的警告,該dylib
在應(yīng)用程序擴(kuò)展中不安全懊直。
接下來扒吁,進(jìn)入Settings
并使用標(biāo)題為其創(chuàng)建快捷方式;像“Post my last article”
有效的工作室囊。
之后雕崩,啟動(dòng)Siri并使用您的快捷方式魁索;Siri將為您發(fā)布該文章,并回復(fù)一個(gè)自定義回復(fù)盼铁,通知您標(biāo)題和發(fā)布日期粗蔚。
6. Wrapping Up
您需要擔(dān)心的最后一件事是從系統(tǒng)中刪除intents
。 假設(shè)用戶刪除了他們編寫的唯一文章饶火。 如果Siri提示他們發(fā)布這篇文章鹏控,那意味著系統(tǒng)會(huì)記住他們想要?jiǎng)h除的信息。
由于這違反了Apple對(duì)用戶隱私的嚴(yán)格尊重肤寝,因此刪除已刪除的活動(dòng)和意圖是您的職責(zé)当辐。
轉(zhuǎn)到ArticleFeedViewController.swift
并滾動(dòng)到文件的底部。
然后醒陆,將以下方法調(diào)用添加到remove(article:indexPath:)
的底部:
INInteraction.delete(with: article.title) { _ in
}
completion
塊允許您對(duì)您認(rèn)為合適的刪除錯(cuò)誤做出反應(yīng)瀑构。
由于新文章快捷方式不包含任何用戶數(shù)據(jù)裆针,因此不一定要?jiǎng)h除它刨摩。
最后,打開Layouts.swift
并找到ArticleFeedViewController
的UITableViewDataSource
擴(kuò)展世吨。 在擴(kuò)展名末尾添加以下內(nèi)容以啟用刪除文章:
func tableView(_ tableView: UITableView,
commit editingStyle: UITableViewCell.EditingStyle,
forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
let article = articles[indexPath.row]
remove(article: article, at: indexPath)
if articles.count == 0 {
NSUserActivity.deleteSavedUserActivities(withPersistentIdentifiers:
[NSUserActivityPersistentIdentifier(kNewArticleActivityType)]) {
print("Successfully deleted 'New Article' activity.")
}
}
}
}
如果需要澡刹,可以使用NSUserActivity
的類方法deleteSavedUserActivities(withPersistentIdentifiers:completionHandler :)
來刪除使用單個(gè)標(biāo)識(shí)符提交的所有活動(dòng)。
如果您想了解有關(guān)Shortcuts
的更多信息耘婚,請(qǐng)查看2018年的兩個(gè)WWDC視頻罢浇。第一個(gè)first presentation涵蓋了許多與本教程相同的材料,并且是一個(gè)很好的復(fù)習(xí)沐祷,以鞏固您在這里學(xué)到的重要想法嚷闭。 第二部分 second更多地涉及最佳實(shí)踐。
后記
本篇主要介紹了構(gòu)建Siri Shortcuts簡(jiǎn)單示例赖临,感興趣的給個(gè)贊或者關(guān)注~~~