转载

实战iOS9【第一天】搜索API

本文翻译自 shinobicontrols  iOS9 Day-by-Day :: Day 1 :: Search APIs

在iOS9之前,你只能在Spotlight中通过名称来找到应用。随着iOS9新的搜索API的公布,Apple现在允许开发者来选择应用中想要索引的内容,还有结果在Spotlight中展示的方式,以及当用户点击一个结果时发生什么。

三个API

NSUserActivity

NSUserActivity API是在iOS8中为Handoff引入的,而在iOS9中则允许搜索activity。你现在可以为这些activity提供元数据,这意味着Spotlight就可以索引它们。它的工作方式和浏览网页时的历史记录类似。用户可以在Spotlight中快速打开最近的activity。

Web Markup

Web Markup允许那些在网站上镜像展示内容的应用在Spotlight中索引内容。用户无需安装应用,也能在Spotlight中展示结果。Apple的索引器会在你的网站上查找特定的markup。然后这会在Safari和Spotlight中展示给用户。

即使你的应用没有安装,也能显示搜索结果,这能增加给潜在用户曝光你的应用的机会。你的应用中公开给搜索API的深度连接会保存在Apple的云端索引中。关于Web Markup更多的信息,参见Apple的文档 Use Web Markup to Make App Content Searchable 。

CoreSpotlight

CoreSpotlight是iOS9的新框架,能让你索引你的应用中的任何内容。NSUserActivity可以用来保存用户的历史,使用它你就可以索引任何你想要的数据。CoreSpotlight主要提供了在用户设备上对CoreSpotlight索引的底层访问。

使用CoreSpotlight API

NSUserActivity 和 WebMarkup API使用起来相对简单,而CoreSpotlight则有一点复杂。为了展示CoreSpotlight API是如何使用的,我们会 创建一个简单的应用来展示朋友的列表,当你点击他们的名字时会展示一个头像。你可以在GitHub( Swift 或 Objective-C )上找到代码,跟着我们一起来试试吧。

实战iOS9【第一天】搜索API

应用有一个简单的storyboard, FriendTableViewController 展示了朋友名字的列表,  FriendViewController 展示了每个朋友的详情。

实战iOS9【第一天】搜索API

朋友的全部信息都保存在类 Datasource 中。在这里我们会创建model并保存朋友的信息,同时也会在这里处理保存信息到CoreSpotlight 索引里的逻辑。 

首先,我们重写类 Datasourceinit() 方法,在这我们创建并保存一个放 Persion 对象的数组。你可能会从数据库或者服务器来加载此类数据,但我们只是展示,创建一些假数据就可以了。

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​​

将person实体保存到Core Spotlight

现在假数据已经有了,我们可以使用iOS9的新API将它们保存到Core Spotlight中。回到类 Datasource ,我们定义了一个 savePeopleToIndex 方法。 FriendTableViewController 可以在view加载完成后调用这个方法。

在这个方法中,我们遍历了 people 数组中的每个人,为每个人创建了一个  CSSearchableItem ,并把这些item保存到一个叫  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)     } })

当你运行应用时,这些数据就会保存了。当你在Spotlight中搜索时,你的朋友的信息就会出现。

实战iOS9【第一天】搜索API

响应用户的选择

现在用户能在Spotlight上看到你的结果啦,很可能他们也会点击结果。但是点击时会发生什么呢?就目前来说,点击结果只会打开你的应用的主界面。如果你希望展示用户点击的朋友,那还需要一点额外的工作。当应用是用这种方式打开时,我们可以通过AppDelegate中UIApplicationDelegate方法来指定应用的行为。

下面是这个方法的完整实现:

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 字典中获取。 在本例中,我们只关心friend ID,它在索引中是保存在item的  kCSSearchableItemActivityIdentifier 下的。

在我们从 userInfo 字典中提取出所需的信息后,我们找到应用的navigation controller,pop to root(不使用动画,这样用户就不会注意到),然后  friendTableViewController 调用 showFriend 方法。关注这个方法如何工作的细节就不讲了,主要就是用给定的ID在数据源中找到对应的friend,然后在navigation controller的栈上push一个新的view controller。 这些就是全部了。现在当用户在Spotlight中点击一个结果时,他们就能看到下面这样的: 

实战iOS9【第一天】搜索API x

现在你能看到,在你的应用的左上角会有一个“Back to Search”的选项。点击它,用户就可以直接返回最开始的搜索界面。用户也可以点击通常的返回按钮在应用中跳转。

总结

在上面的例子中,我们看到了将你的应用的数据整合到 CoreSpotlight 索引中是多简单,通过这种方法让用户打开你的应用是多强大,对用户查找特定信息来说是多方便。

但是我们还没有讲到如何从索引中删除数据。你应该尽量保持你的应用的索引数据是最新的,这很重要。关于如何在CoreSpotlight中删除旧的实体,可以看看 deleteSearchableItemsWithIdentifiers 、  deleteSearchableItemsWithDomainIdentifiers 和  deleteAllSearchableItemsWithCompletionHandler 方法。

表现良好的重要性

可能看起来在Spotlight和Safari中尽可能多地出现是个不错的主意,但是在将索引填满你的信息之前最好还是仔细考虑一下。在iOS生态系统中表现良好,不仅对于保持用户开心很重要,同时Apple也会注意到。Apple在保护相关内容上显然投资不少,搜索结果的出现率会被追踪,垃圾信息会被移到搜索结果的最下面。

更多

关于新的搜索API的更多信息,我推荐观看WWDC session 709, Introducing Search APIs . 你可能对  NSUserActivity Class Reference 和  documentation for CoreSpotlight 也感兴趣。别忘了,如果你想试试本文里讲到的内容,可以在GitHub( Swift 或 Objective-C )上找到代码。

正文到此结束
Loading...