资讯专栏INFORMATION COLUMN

iOS 9 每天了解多一点 :: 第1天 :: 搜索API

lentoo / 2775人阅读

摘要:想进一步了解,可以看看苹果的官方文档。苹果花了很多心思来保证搜索结果是真正相关的,他们会跟踪搜索结果点击率,而灌水会导致被挪到搜索结果的末尾。

译者前言:
本文为 shinobicontrols 的开发者 Chris Grant 的系列文章《iOS 9 Day-by-Day》(中文名取为《iOS 9 每天了解多一点》)中文翻译的其中一篇。系列文集:iOS 9 每天了解多一点。虽然名为“Day-by-Day”,实际上原作者是每周写一、两篇。不想错过更新的朋友,欢迎关注我的微博 @戴仓薯,一旦有更新我会发微博。对翻译有任何意见和建议,请在文章下留言。Have fun learning iOS 9:)

在 iOS 9 之前,Spotlight 里只能搜索 app 的名字。随着 iOS 9 新公布的搜索 API,苹果现在允许开发者来定制自己 app 里能被搜到的内容,搜索结果在 Spotlight 里显示的方式,以及用户点击搜索结果的事件。

3 个搜索 API NSUserActivity

NSUserActivity API 是 iOS 8 介绍新功能 Handoff 时引入的,不过在 iOS 9 里,Spotlight 也能搜索到 activity。你现在可以给 acitivity 提供 metadata,表示这个 activity 是能搜到的。实际用起来是一个历史记录栈,跟你平常浏览网页类似。用户可以从 Spotlight 里快速打开最近使用过的 activity。

Web Markup

Web Markup 的机制是,app 可以把内容镜像到一个网站上,然后 Spotlight 就会索引里面的内容。即使用户设备上没装这个 app,Spotlight 里也能显示出搜索结果。苹果的爬虫会在网络上持续爬取,寻找网站上的特定 markup。之后搜索结果在 Safari 里和 Spotlight 里都会出现。

即使用户没装这个 app,都能搜到结果,所以这个功能至关重要,它能给你带来很多在潜在用户面前曝光的机会。你暴露给搜索 API 的 app 里的深度链接,会被存到苹果的云索引上。想进一步了解 Web Markup,可以看看苹果的官方文档 Use Web Markup to Make App Content Searchable。

CoreSpotlight

CoreSpotlight 是一个 iOS 9 的新框架,能让你索引 app 里的任何内容。之前提到的 NSUserActivity 可以用来保存用户的历史信息,而这个新的 API 可以索引任何数据。它为你接触到用户设备上的 CoreSpotlight 索引提供了必不可少的桥梁。

使用 Core Spotlight API

NSUserActivity 和 Web Markup API 相对来说用起来比较容易,而 CoreSpotlight 就要复杂一些。为了演示新的 CoreSpotlight API 是怎么用的,我们来做一个简单的 app 吧。它的功能就是显示一个朋友列表,点击朋友名字的时候显示一张肖像。你可以在GitHub上下载到源代码,一步一步跟着做。

App里有一个简单的 storyboard,里面有一个FriendTableViewController,显示简单的朋友列表;还有一个FriendViewController,显示每个朋友的细节。

所有朋友的信息都存在Datasource类里。我们用这个类来创建保存朋友信息的 model,另外,把朋友保存到 Core Spotlight 索引的逻辑也写在这个类里。

首先,我们重写Datasource类的init()方法,在这个方法里创建并保存一个Person数组。可能数据一般应该是从数据库、服务器接口等处读出来的,为了演示起见,我们就简单写一些假数据吧。

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 上

现在有了假数据,我们就可以用上 iOS 9 的新 API,把它存到 Core Spotlight 上了。回到Datasource类,我们在这个类里定义了一个方法savePeopleToIndexFriendTableViewController的界面加载完毕后,就可以调用这个方法。

在这个方法里,我们循环遍历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 的AppDelegatecontinueUserActivity 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 的过程干扰了),然后调用friendTableViewControllershowFriend方法。这个方法的细节我就不多说了,总之就是根据 ID 从 datasource 里找到对应的朋友,然后 push 进来一个新的 view controller。收工啦!现在当用户点击 spotlight 里的朋友时,他们会看到下面的画面:

截图上可以看到,app的左上角有一个“Back to Search”按钮。点击这个按钮会直接回到搜索结果页面,就是刚才点击朋友名字的那个页面。用户还可以点击标准的返回按钮,接着在 app 里面逛。

Demo 小结

在上面这个 demo 里,我们展示了整合 app 的数据与CoreSpotlight索引如此简单,引导用户打开 app 的功能如此强大,以及对用户搜索特定内容如此有帮助。

不过,我们并没提到怎么从索引里删除数据。这一点还是很重要的,应该勤于更新索引的数据。想进一步了解如何从 CoreSpotlight 删除旧数据,可以看看 deleteSearchableItemsWithIdentifiersdeleteSearchableItemsWithDomainIdentifiers 以及 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
译者:@戴仓薯

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/15773.html

相关文章

  • iOS 9 了解一点 :: 目录

    摘要:译者前言从今天起,仓薯会开始翻译的开发者的系列文章中文名取为每天了解多一点,发布在简书上,并随原作者更新。这是每天了解多一点的一大亮点不只是用文字介绍新功能,还有在实际工程中的应用。 译者前言: 从今天起,仓薯会开始翻译 shinobicontrols 的开发者 Chris Grant 的系列文章《iOS 9 Day-by-Day》(中文名取为《iOS 9 每天了解多一点》),发布在...

    changfeng1050 评论0 收藏0
  • 我是如何在自学编程9个月后找到工作的

    摘要:昨天在我在国外网站上看到一篇文章,作者分享了他自学编程个月后找到工作的经历。而本文中,我主要针对想要通过学习编程找工作的角度来谈。我在年月犯了一个错误我认为首要任务是找到一份前端开发的工作。 昨天在我在国外网站 reddit 上看到一篇文章,作者分享了他 自学编程 9 个月后找到工作 的经历。文章不到一天就得到3千多赞,2百条回复。我看了下内容,非常中肯,其中有不少建议也是我在编程教室...

    gaosboy 评论0 收藏0
  • 7期 Datawhale 组队学习计划

    马上就要开始啦这次共组织15个组队学习 涵盖了AI领域从理论知识到动手实践的内容 按照下面给出的最完备学习路线分类 难度系数分为低、中、高三档 可以按照需要参加 - 学习路线 - showImg(https://segmentfault.com/img/remote/1460000019082128); showImg(https://segmentfault.com/img/remote/...

    dinfer 评论0 收藏0
  • 我的自学编程故事

    摘要:问题如何自学编程想自学编程,从何入手。后来证明我们当时来上海的决定是正确的。 前言 之前有人留言说想看我的所谓奋斗史,前天的这篇调查「以产品思维去做微信公众号」也显示这部分人比例还不少,今天突然想到我在2年前在知乎回答过一个「如何自学Android编程」的问题,今天特地去重新看了一遍,2年多的时间再次看这篇文章勾起了我不少的回忆,很感谢当初的回答,记录了我人生的一个阶段,给我留下了人生...

    番茄西红柿 评论0 收藏0
  • ELK初体验-Nginx日志实时分析

    摘要:也就是说它能被查询,但不能被取回显示。自定义路由值可以确保所有相关文档比如用户的文章按照用户账号路由就可以实现属于同一用户的文档被保存在同一分片上。分片与副本交互新建索引和删除请求都是写操作,它们必须在主分片上成功完成 写在前面从初次了解elastic产品到正式投入使用,拖拖拉拉的也有小半年了,刚接触的时候看到一些帖子都是安装教程,后来看到一些都是深入教程,此篇文章较居中一点,总结了我...

    pumpkin9 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<