搜尋 API 提供了許多有趣的新方法,可以與使用者互動。在 iOS 9 中, Apple 優化了 Spotlight ,加入令人驚豔的新功能,可以為更多的內容建立索引。舉例而言,使用者可以透過 Spotlight 搜尋網頁內容或者 App 內部的資料。此外也可以透過熱門關鍵字輕易地開啟 App (無論關鍵字是否包含 App 的名稱)!搜尋 API 可以幫助你達成這些任務。
對於開發者而言,在 iOS 9 中實現搜尋將是一大特色。隨著 iOS 9 的發佈,現在正是學習的最佳時刻。 Apple 在搜尋產業默默無聞,但是隨著 iOS 9 提供了搜尋 API ,情況可能就此改觀!
iOS 9 SDK 中新的搜尋 API 包含下列 3 個主要元件:
- NSUserActivity ,可以建立關鍵字及其他內容的索引
- Web Markup ,針對 Spotlight 優化建立網頁索引,支援 App 的「深度連結」( Deep Linking )與通用連結( Universal Link )。
- Core Spotlight ,可以針對 App 的所有內容建立深度連結。
在本文中,我們將會介紹這 3 組搜尋 API 。但是因為篇幅有限,我們並不會深入講解 Core Spotlight (最進階的搜尋 API )。
在本文的後半部中,我們將會探索 SFSafariWebController
並且說明為何你應該在自己的 App 中加以使用。
開始使用
讓我們從下載 Starter 專案開始吧。下載後解壓縮,並在實機或模擬器上執行(必須搭配 Xcode 7.0 以上版本,才能夠使用 iOS 9 SDK )。你將看到擁有單一視圖控制器畫面的簡單 App 。
你會發現 ViewController.swift
檔案並沒有太多的內容。沒什麼值得說明之處。本文並不需要預先特別準備些什麼,而且我們也不打算直接處理接續互通( Handoff )。不過在使用搜尋 API 時(尤其是 Core Spotlight ),一般都會使用到接續互通,因為你很可能會想要開啟特定的視圖控制器或是顯示特定的內容。
在本文中,我們只會專注於實現 App 內容索引的建立,讓使用者能夠透過 Spotlight 來存取 App 。我們將在其他篇文章中陸續介紹這些更進階的功能。
NSUserActivity
讓我們從 NSUserActivity 開始。此類別是在 WWDC 2014 介紹 iOS 8 時首次揭露,在 iOS 9 時改版一躍成為令人期待的新功能。我們在本文中並不會直接討論接續互通(因為那需要另外寫篇文章來大書特書),你只需要知道 NSUserActivity
類別是接續互通 API 的一員。假使你不熟悉接續互通,我推薦你閱讀由 Gabriel 所寫的文章。
現在讓我們進入正題吧。首先我們要在 ViewController.swift
的 viewDidLoad()
函式中將 NSUserActivity
物件初始化:
let myActivity = NSUserActivity(activityType: "com.appcoda.searchAPIs.detail") myActivity.title = "Cupertino" myActivity.eligibleForSearch = true myActivity.keywords = Set(arrayLiteral: "Cupertino", "Silicon Valley", "California", "San Jose", "San Francisco", "Apple Inc", "Mothership") self.userActivity = myActivity myActivity.eligibleForHandoff = false myActivity.becomeCurrent()
在第 1 行中,我們初始化新的 NSUserActivity
物件,並為本專案連結不重複的識別碼。
第 2 行設定標題屬性 ── 在本例中,此視圖控制器所在城鎮是 Cupertino 。
在第 3 行中,我們將此物件設定為適合搜尋(因為我們將使用搜尋 API ,所以這點很重要)。
接著,我們建立了一個關鍵字集合(透過 arrayLiteral )。當我們的使用者運用 Spotlight 進行搜尋時,這些關鍵字將會跟著顯示出來。
隨後在第 5 行中, userActivity
屬性被指派為 myActivity ,而在第 6 行中, eligibleForHandoff
屬性被設定為 false 。因為我們並未在本文中直接使用接續互通,所以我們可以很安全地將此屬性設定為 false 。
最後在第 7 行中,我們呼叫了 myActivity 的 becomeCurrent()
函式。此函式會將此活動新增到 Spotlight 中,並針對其內容建立索引。
現在,在模擬器或實機上執行此 App 。一旦在裝置上成功執行,接著請關閉此 App 並且下拉主畫面以便看到 Spotlight 。輸入「 San Jose 」(我們在稍早所指派的關鍵字之一),或是其他你所自建的關鍵字。你將會看見帶有輸入關鍵字的 App !很有趣對吧。
如你所見,在 iOS 9 App 中加入 NSUserActivity 並且允許使用者透過關鍵字搜尋來找到你的 App ,這一點也不困難。
Web Markup
Web Markup 是 Apple 在 WWDC 中宣佈的 3 項搜尋 API 中的第 2 項。透過 Web Markup ,開發者可以使用深度連結來製作可被搜尋的內容。 Apple 建議可以使用此 API 將任意 App 內容鏡射成網頁。如果你的 App 有一些網頁內容,那麼使用 Web Markup 可以讓 Applebot 網頁爬蟲( Web Crawler )針對你的內容建立索引。最重要的是,建立索引後的內容可以被所有 iOS 使用者在 Spotlight 和 Safari 搜尋結果中找到。這無疑增加了 App 的曝光度和黏著度( Engagement )。
根據 Apple 的文件,要啟用 Web Markup 必須先完成下列這 4 件事:
- 允許 Apple 利用 Applebot ( Apple 的網頁爬蟲)來探索和擷取你的 App 網站。
- 確定你的 App 網站採用了支援深度連結的網頁標記。
- 確定你的 App 本身能夠處理深度連結。
- 針對豐富的資料和結構化資料加入標記,以便被搜尋。
假使你尚未開始在網站上使用智慧 App 看板( Smart App Banners ),現在正是採用的最佳時刻。
透過 Web Markup ,使用者可以直接從網站下載 App (而且不會跳離 Safari ,確保操作不會中斷)。智慧 App 看板並無新意,但是隨著 Web Markup 的加入, Apple 現在非常鼓勵開發者加以採用。你可以透過下列的 HTML 中繼標籤在自己的網站中加入智慧 App 看板。
為了要讓你的 App 出現,必須傳入 App ID ,這組識別碼可以在 iTunes Connect 上找到(只要該 App 仍存活於 App Store )。這樣就可以讓看板顯示出來了!
你也可以透過使用 iTunes Connect 來確保 Applebot 能夠找到並擷取你的網站。在 iTunes Connect 的支援和行銷欄位中輸入 App 的 URL 。除此之外, Apple 現在也有支援通用連結。
在通用連結之前,要啟動 App 需要在 App 的 info.plist
中註冊 URL 配置( Scheme ) ,然後才能呼叫該連結。隨後將會開啟 Safari ,接著重導至 App Store 或是開啟 App 。這些動作都需要使用特殊的 URL 配置,例如 facebook:// 。
這麼做顯然不夠理想。通用連結允許使用者透過標準的 HTTP 連結來啟動 App 。這點為何重要?以 Twitter 為例。假使 Twitter 採用了通用連結,那麼瀏覽 twitter.com 將會啟動 Twitter App (如果有安裝的話)。這樣大幅簡化了使用者體驗,而不會在 Safari 中出現空白的分頁(這在 iOS 8 之前是個長久存在的問題)。
因為需要一台伺服器以便測試通用連結,所以我們並不會實際展示,而只會提供相關知識讓你開始此程序。處理通用連結是個惱人的過程,不過遵循下列的步驟可以協助你完成設定。請留意,通用連結需要使用到接續互通(再度重申本文將不會介紹此技術)。更精確地說,我們無法介紹完所有事項的運作原理。使用通用連結的 App 必須在 Capabilities 分頁中將「 Associated Domains 」切換為 ON 。
接著,你必須建立、簽署和上傳名為 apple-app-site-assocation.json
的檔案到網站(支援 https )伺服器的根目錄。此字典檔的詳細內容如下。你應該有注意到,需要在 App 完整的 Bundle ID 中前綴團隊 ID 。 此資訊可以在 iTunes Connect 或 Xcode 專案設定中找到。
{ "applinks": { "apps": [], "details": { "TBEJCS6FFP.com.yourdomain.yourapp”: { "paths":[ "*" ] } } } }
接著需要設定 entitlements 檔案(回到 Xcode ),設定與該檔案相符的合適網域,並且在 AppDelegate.swift 中實作下列函式。
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler:([AnyObject]!) -> void) -> Bool { // 這是接續互通 API }
Web Markup 是功能強大的全新搜尋 API 。隨著 Applebot 擷取網頁的內容與通用連結, Spotlight 將逐漸成為勢力龐大的網路搜尋器,而通用連結則是過程當中的最佳幫手!
Core Spotlight
現在來見識一下 Core Spotlight 的威力吧,它可是搜尋 API 的主角。 Core Spotlight 是從 iOS 9 SDK 才正式導入的全新搜尋 API 。相較於前面提到的 2 組 API ,這組 API 是目前功能最豐富的。 Core Spotlight 與接續互通息息相關,這意味著必須對於接續互通技術有所認識。因為本文並不會直接探討接續互通,所以我們將只會介紹 Core Spotlight ,而將接續互通留待後續的文章再做更進一步的介紹。
Core Spotlight 就跟 NSUserActivity
一樣,是用來針對搜尋結果建立索引。然而與 NSUserActivity
不同的是, Core Spotlight 的運作與接續互通息息相關!因此,使用者在 Spotlight 中搜尋特定的關鍵字時,將可以直接被帶領到個別的視圖控制器。
Apple 隨附的 App (諸如郵件、聯絡資訊和備忘錄)也都使用了 Core Spotlight ,因此開發者可以在他們自己的 App 中顯示內容。你可以定義文章(透過中繼資料)之類的可搜尋項目,並將其放置到雲端索引( Cloud Index )當中。該項目隨後將可以被 Spotlight 搜尋找到。
在未來的文章當中,我們將會花更多篇幅來介紹這組威力強大的全新 API 。就目前而言,只要知道有這組 API 的存在,而且必須與接續互通 API 緊密合作就夠了。
新的 SFSafariViewController 類別
在本文的後半部中,我們將會討論 SFSafariViewController
,這是 iOS 9 才導入的全新類別,開發者們將會驚訝於它的無限潛力。儘管不是搜尋 API ,不過 SFSafariViewController
最近因為其易用性引起熱議,而且能夠將網頁內容整合到 Safari 瀏覽器之中。此外 SFSafariViewController
也能夠與搜尋 API 搭配使用。舉例而言,假使你透過關鍵字來為自己的 App 建立索引,而其中一個視圖控制器顯示的是網頁內容,那麼將非常適合使用 SFSafariViewController
!
多年以來,開發者一直都是使用 UIWebView (最近改成了 WKWebView ── 關於 WKWebView 類別的介紹,請看這篇文章)。 UIWebView 最為人詬病之處在於其 JavaScript 引擎的速度比 Safari 慢,而且效能也不佳。在 WWDC 2014 時, Apple 針對開發者們關於效能改進的抱怨,首度導入了 WKWebView
。 WKWebView
需要使用 Web Kit 框架,並了解 Web Kit 委派函式如何使用。我鼓勵有興趣的讀者們可以嘗試學習這項技術,不過本文的主題只鎖定在 SFSafariViewController
。
今年, Apple 在 SFSafariViewController
中導入了許多振奮人心的新改變。許多使用者想要在他們的 App 中使用完整的 Safari 瀏覽器功能,但是又不希望強制使用者跳離 App 去使用 Safari 瀏覽器(這會影響使用者留存率),或者沒有時間去建置內建於 App 中的瀏覽器。藉由在 App 中提供等同於 Safari 瀏覽器的功能而不是提示使用者開啟 Safari 瀏覽器, SFSafariViewController
讓許多人看見了曙光。
SFSafariViewController
的設定步驟非常簡單。重新開啟本文稍早所下載的 Starter 專案,然後在 Storyboard 中建立名為 didPressButton()
的 IBAction 。我們將在此 IBAction 中撰寫有關 SFSafariViewController
的程式碼。相較於在 Safari 或是 WKWebView 中開啟,點擊此按鈕將會開啟 SFSafariViewController
視圖控制器。
讓我們從匯入 Safari 服務開始吧。只需要在我們的 View Controller 的開頭加入下列的匯入陳述式即可。
import SafariServices
接著,因為我們需要處理一些委派函式,所以必須符合 SFSafariViewControllerDelegate 的規範。在類別宣告的後面,加入:
SFSafariViewControllerDelegate
現在類別宣告應該如下所示。
class ViewController: UIViewController, SFSafariViewControllerDelegate {
太棒了。在匯入完 Safari 服務之後,我們接著可以將 SFSafariViewController
實體化,並且設定其屬性。讓我們在 didPressButton()
IBAction 中撰寫一些程式碼吧。
let safariVC = SFSafariViewController(URL:NSURL(string: "https://en.wikipedia.org/wiki/Cupertino,_California")!, entersReaderIfAvailable: true) safariVC.delegate = self self.presentViewController(safariVC, animated: true, completion: nil)
在第 1 行中,我們只是初始化 SFSafariViewController
,傳入包裹成 NSURL 物件的字串當作參數,並將 entersReaderIfAvailable
設定為 true
。因為我們想要顯示的是 Wikipedia 的內容,所以使用的是閱讀器( Reader )的功能。假使你尚不熟悉閱讀器,請容我告訴你,閱讀器是 Safari 中一個很方便的功能,可以從網站擷取並顯示重要的內容。
在下一行中,我們將委派設定為 self
,亦即目前的視圖控制器的實體。
在第 3 行中,我們呼叫了 self.presentViewController
,並傳入 SFSafariViewController
以及布林數值 true 。此外也將完成處理常式設定為 nil 。
另一方面,藉由將上述的布林數值從 true
改為 false
,你也可以在 SFSafariViewController
中檢視此網頁而不啟用閱讀器模式。
let safariVC = SFSafariViewController(URL:NSURL(string: "https://en.wikipedia.org/wiki/Cupertino,_California")!, entersReaderIfAvailable: false)
假使你仍不熟悉閱讀器的用法,可以仔細檢視下圖,應該就會對於啟用和停用閱讀器的差別有比較好的認識了。
若要關閉 SFSafariViewController
,我們可以呼叫下列的委派函式:
safariViewControllerDidFinish
在 didPressButton()
函式的後面加入下列的程式碼。
func safariViewControllerDidFinish(controller: SFSafariViewController) { controller.dismissViewControllerAnimated(true, completion: nil) }
這段程式碼非常直覺。我們在第 1 行呼叫了委派函式,並在該函式中呼叫了:
controller.dismissViewControllerAnimated()
傳入布林數值 true
指示關閉視圖控制器,並將完成閉包( Closure )設定為 nil
。別擔心 nil 參數;那只是用來佔據閉包的位置(閉包是 Swift 中的進階概念)。
至此,便完成了 iOS 9 中的 SFSafariViewController
實作 ── 而且一點也不難!
結語
我們在本文中涵蓋了許多 iOS 9 的內容。在前半部中,我們介紹了 3 組搜尋 API ,以及它們能夠替開發者帶來什麼魔法。這些搜尋 API ( NSUserActivity 、 Web Markup 和 Core Spotlight )為開發者提供了與使用者更加緊密互動的方法。我們看到如何運用 NSUserActivity
來為 App 內容建立索引以及如何與 Web Markup 搭配使用。為了示範,我們也討論了智慧 App 看板和通用連結。
在後半部中,我們介紹了 SFSafariViewController
並說明了如何在自己的 App 中實現。 UIWebViews/WKWebViews
已成回憶。有了 SFSafariViewController
,你可以在 App 中嵌入網頁,並且完整運用 Safari 網頁瀏覽器的功能,而不需要跳離 App 。這麼做可以提昇使用者的黏著度,而不必強迫使用者開啟外部的瀏覽器。我們討論了實作此類別有多麼簡單,也示範了如何使用委派函式。
供你參考,請從這裡下載本文的完整 Xcode 專案檔案。
希望本文對你有所幫助,請在留言中回饋你的意見。讓你的 App 準備好接受 iOS 9 和搜尋 API 的洗禮吧!
原文:Getting Started with Search APIs and SFSafariViewController in iOS 9