译者前言:
本文为 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
译者:@戴仓薯