譯者前言:
本文爲 shinobicontrols 的開發者 Chris Grant 的系列文章《iOS 9 Day-by-Day》(中文名取爲《iOS 9 天天瞭解多一點》)中文翻譯的其中一篇。系列文集:iOS 9 天天瞭解多一點。雖然名爲「Day-by-Day」,實際上原做者是每週寫1、兩篇。不想錯過更新的朋友,歡迎關注個人微博 @戴倉薯,一旦有更新我會發微博。對翻譯有任何意見和建議,請在文章下留言。Have fun learning iOS 9:)html
在 iOS 9 以前,Spotlight 裏只能搜索 app 的名字。隨着 iOS 9 新公佈的搜索 API,蘋果如今容許開發者來定製本身 app 裏能被搜到的內容,搜索結果在 Spotlight 裏顯示的方式,以及用戶點擊搜索結果的事件。ios
NSUserActivity API 是 iOS 8 介紹新功能 Handoff 時引入的,不過在 iOS 9 裏,Spotlight 也能搜索到 activity。你如今能夠給 acitivity 提供 metadata,表示這個 activity 是能搜到的。實際用起來是一個歷史記錄棧,跟你日常瀏覽網頁相似。用戶能夠從 Spotlight 裏快速打開最近使用過的 activity。git
Web Markup 的機制是,app 能夠把內容鏡像到一個網站上,而後 Spotlight 就會索引裏面的內容。即便用戶設備上沒裝這個 app,Spotlight 裏也能顯示出搜索結果。蘋果的爬蟲會在網絡上持續爬取,尋找網站上的特定 markup。以後搜索結果在 Safari 裏和 Spotlight 裏都會出現。github
即便用戶沒裝這個 app,都能搜到結果,因此這個功能相當重要,它能給你帶來不少在潛在用戶面前曝光的機會。你暴露給搜索 API 的 app 裏的深度連接,會被存到蘋果的雲索引上。想進一步瞭解 Web Markup,能夠看看蘋果的官方文檔 Use Web Markup to Make App Content Searchable。數據庫
CoreSpotlight 是一個 iOS 9 的新框架,能讓你索引 app 裏的任何內容。以前提到的 NSUserActivity 能夠用來保存用戶的歷史信息,而這個新的 API 能夠索引任何數據。它爲你接觸到用戶設備上的 CoreSpotlight 索引提供了必不可少的橋樑。api
NSUserActivity 和 Web Markup API 相對來講用起來比較容易,而 CoreSpotlight 就要複雜一些。爲了演示新的 CoreSpotlight API 是怎麼用的,咱們來作一個簡單的 app 吧。它的功能就是顯示一個朋友列表,點擊朋友名字的時候顯示一張肖像。你能夠在GitHub上下載到源代碼,一步一步跟着作。數組
App裏有一個簡單的 storyboard,裏面有一個FriendTableViewController
,顯示簡單的朋友列表;還有一個FriendViewController
,顯示每一個朋友的細節。服務器
全部朋友的信息都存在Datasource
類裏。咱們用這個類來建立保存朋友信息的 model,另外,把朋友保存到 Core Spotlight 索引的邏輯也寫在這個類裏。網絡
首先,咱們重寫Datasource
類的init()
方法,在這個方法裏建立並保存一個Person
數組。可能數據通常應該是從數據庫、服務器接口等處讀出來的,爲了演示起見,咱們就簡單寫一些假數據吧。session
override init () { let becky = Person() becky.name = "Becky" becky.id = "1" becky.image = UIImage(named: "becky")! ... people = [becky, ben, jane, pete, ray, tom] }
people
數組存好數據以後,Datasource
就準備就緒啦!
這邊數據已經準備完畢,FriendTableViewController
就能夠建立一個Datasource
的實例,在 table view 要顯示 cell 的時候使用。
let datasource = Datasource()
在cellForRowAtIndexPath
方法裏,顯示 cell 內容的代碼以下:
let person = datasource.people[indexPath.row] cell?.textLabel?.text = person.name
如今有了假數據,咱們就能夠用上 iOS 9 的新 API,把它存到 Core Spotlight 上了。回到Datasource
類,咱們在這個類裏定義了一個方法savePeopleToIndex
。FriendTableViewController
的界面加載完畢後,就能夠調用這個方法。
在這個方法裏,咱們循環遍歷people
數組裏的每個 person,爲每個 person 分別建立一個 CSSearchableItem
,存到一個臨時數組searchableItems
裏。
let attributeSet = CSSearchableItemAttributeSet(itemContentType: "image" as String) attributeSet.title = person.name attributeSet.contentDescription = "This is an entry all about the interesting person called (person.name)" attributeSet.thumbnailData = UIImagePNGRepresentation(person.image) let item = CSSearchableItem(uniqueIdentifier: person.id, domainIdentifier: "com.ios9daybyday.SearchAPIs.people", attributeSet: attributeSet) searchableItems.append(item)
最後一步是在默認的CSSearchableIndex
上調用indexSearchableItems
。這一步就真正把這些 item 存到 CoreSpotlight 裏了,此後用戶就能夠搜索這些數據,會在搜索結果裏出現。
CSSearchableIndex.defaultSearchableIndex().indexSearchableItems(searchableItems, completionHandler: { error -> Void in if error != nil { print(error?.localizedDescription) } })
完事兒了!把 app 跑起來,數據會實時加入存儲;在 spotlight 裏一搜,就能搜到你的朋友啦~
如今用戶能在 Spotlight 裏看到你的搜索結果了,希望他們會點上一點!但若是他們真點了,會發生什麼呢?就此刻而言,點擊搜索結果只會跳轉打開你的 app。若是你想要展現出用戶剛點擊的那位朋友,還得再寫點代碼。咱們能夠在 app 的AppDelegate
的 continueUserActivity UIApplicationDelegate
方法裏指定 app 從搜索結果打開以後的行爲。
如下是這整個方法的代碼:
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool { // Find the ID from the user info let friendID = userActivity.userInfo?["kCSSearchableItemActivityIdentifier"] as! String // Find the root table view controller and make it show the friend with this ID let navigationController = (window?.rootViewController as! UINavigationController) navigationController.popToRootViewControllerAnimated(false) let friendTableViewController = navigationController.viewControllers.first as! FriendTableViewController friendTableViewController.showFriend(friendID) return true }
如代碼所示,以前咱們用indexSearchableItems
方法存在 CoreSpotlight 索引裏的信息,如今能夠用userActivity.userInfo
獲取到。這裏咱們惟一感興趣的就是朋友的 ID,這個 ID 咱們保存在索引 item 的kCSSearchableItemActivityIdentifier
裏了。
咱們從userInfo
字典裏提取出 ID 以後,下一步是獲取到 app 的 navigation controller,pop 到首頁(不帶動畫,這樣用戶就不會被 pop 的過程干擾了),而後調用friendTableViewController
的showFriend
方法。這個方法的細節我就很少說了,總之就是根據 ID 從 datasource 裏找到對應的朋友,而後 push 進來一個新的 view controller。收工啦!如今當用戶點擊 spotlight 裏的朋友時,他們會看到下面的畫面:
截圖上能夠看到,app的左上角有一個「Back to Search」按鈕。點擊這個按鈕會直接回到搜索結果頁面,就是剛纔點擊朋友名字的那個頁面。用戶還能夠點擊標準的返回按鈕,接着在 app 裏面逛。
在上面這個 demo 裏,咱們展現了整合 app 的數據與CoreSpotlight
索引如此簡單,引導用戶打開 app 的功能如此強大,以及對用戶搜索特定內容如此有幫助。
不過,咱們並沒提到怎麼從索引裏刪除數據。這一點仍是很重要的,應該勤於更新索引的數據。想進一步瞭解如何從 CoreSpotlight 刪除舊數據,能夠看看 deleteSearchableItemsWithIdentifiers
,deleteSearchableItemsWithDomainIdentifiers
以及 deleteAllSearchableItemsWithCompletionHandler
方法。
儘管讓 Spotlight 和 Safari 索引到的 app 內容彷佛越多越好,在大肆往裏灌水以前仍是要三思。在 iOS 生態系統裏保持節操,不只能讓用戶更舒服,並且蘋果也盯着呢。蘋果花了不少心思來保證搜索結果是真正相關的,他們會跟蹤搜索結果點擊率,而灌水會致使被挪到搜索結果的末尾。
想要進一步瞭解新的搜索 API,推薦看一看 WWDC session 709,介紹搜索 API。你也可能會對 NSUserActivity Class Reference與CoreSpotlight 文檔感興趣。別忘了,若是想要試試本文描述的 demo,能夠在GitHub上下到源碼。
原文地址:iOS9 Day-by-Day :: Day 1 :: Search APIs
原做者:Chris Grant
本文地址:http://www.jianshu.com/p/160e10bd6552
系列文集:http://www.jianshu.com/notebooks/1354465/latest
譯者:@戴倉薯