iOS 9: Day by Day 第一天 搜索API

本文翻译自Chris Grant的《iOS 9 Day by Day :: Day 1 :: Search APIs》(https://www.shinobicontrols.com/blog/ios9-day-by-day-day1-search-apis)。感谢Chris Grant的辛苦工作!

iOS 9之前,我们只能在Spotlight中根据名字搜索应用程序。苹果在iOS 9上引入了搜索API,允许开发者在应用内指定可以被Spotlight索引和呈现的内容。

三个API

NSUSerActivity

iOS 8引入NSUserActivity API是为了Handoff,而iOS 9允许我们对活动进行搜索。给这些活动设置元数据(Metadata)后,Spotlight就可以对它们进行索引。所有的活动会跟浏览网页一样形成一个历史记录栈。用户可以在Sptlight里快速打开已有的活动。

Web Markup

Web Markup允许应用程序将它们的内容映射到一个网站,从而在Spotlight里进行索引。用户不需要在设备上安装Spotlight里出现的应用。苹果的索引器能够抓取我们的网站来获取所需的信息,抓取结果通过Safari和Spotlight提供给用户。

在没有安装应用的设备上进行展示是一个非常重要的特征,这能增加我们的应用在潜在用户前的曝光度。应用程序暴露给搜索API的深度链接被存储在苹果的云索引服务器上。更多关于Web Markup的信息请查看《Use Web Markup to Make App Content Searchable》。

CoreSpotlight

CoreSpotlight是一个新的iOS 9框架,它允许我们在应用程序里对任何内容进行索引。NSUserActivity也可以用于保存用户历史。本质上它给我们提供了访问CoreSpotlight索引的能力。

使用Core Spotlight API

NSUserActivity与Web Markup API用起来要比CoreSpotlight要简单。下面我们通过一个简单的应用来说明Core Spotlight API如何工作。这个程序会显示一个好友列表,当点击名字可以看到一个照片。可以在GitHub上找到示例代码。

应用程序使用Storyboard创建界面,其中包含一个FriendTableViewController显示好友列表,而FriendViewController显示好友详情。

好友信息保存在名为Datasource的类中。我们在这个类里创建保存好友信息的数据模型,并且包含操作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对象。

let datasource = Datasource()

cellForRowAtIndexPath函数中显示好友名称:

let person = datasource.people[indexPath.row]
cell?.textLabel?.text = person.name

保存people入口到Core Spotlight

下面我们使用iOS 9中新的API来将数据保存到Core Spotlight中。回到Datasource类,定义一个名为savePeopleToIndex的函数。FriendTableViewController在视图被加后可以调用该方法。

savePeopleToIndex方法中遍历people数组中的每个人,并且创建对应的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.tumbnailData = UIImagePNGRepresentation(person.image)
let item = CSSearchableitem(uniqueIdentifier: person.id, domainIdentifier: "com.ios9daybyday.SearchAPIs.people", attributeSet: attributeSet)
searchableItems.append(item)

最后一步是在默认的CSSearchableIndex上调用indexSearchableItems。这一步实际上是将数据保存到CoreSpotlight,这样用户就可以在Spotlight的搜索结果中看到它们了。

响应用户选择

当用户看到Spotlight中的搜索结果后,有可能会点击它们。但是这样做的结果只是打开了应用的主界面。如果希望在点击了一个朋友后,显示它的详细情况,我们还需要做更多的事情。首先需要定制AppDelegate中通过continueUserActivity打开应用后执行的UIApplicationDelegae的方法。

下面是整个方法的实现:

func appliction(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
    //查找用户ID
    let friendID = userActivity.userInfo?["kCSSearchableItemActivityIdentifier"] as! String
    
    //查找根视图控制器并且显示用户信息
    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,它被作为kCSSearchableItemActivityIdentifier存储在索引中。

一旦我们将userInfo中的数据取出来,就可以去获取应用程序的导航控制器,并且跳转到根视图,然后通过friendTableViewController里的showFriend方法显示好友详情。结果如下:

在屏幕的左上角有一个“返回搜索”的选项,点击可以返回搜索界面。

示例总结

在上面的示例代码里,我们可以看到如何将应用程序的数据整合到CoreSpotlight索引。然后Spotlight如何将我们引导到程序中对应的页面。

我们还没有涉及到如何将数据从索引中移除,但总是保持索引中的数据为最新的很重要。如果需要从CoreSpotlight中移除老的数据,请查看deleteSearchableItemsWithIdentifiersdeleteSearchableItemsWithDomainIdentifiersdeleteAllSearchableItemsWithCompletionHandler方法。

好公民的重要性

将尽可能多的内容索引到Spotlight和Safari看起来很不错,但这么做之前一定要记得三思。成为一个对iOS生态系统有益的好公民不止能够让你的客户体验更好,而且会引起苹果的注意。它们做了许多事情去跟踪、分析哪些垃圾制造者,并将它们放到最后面。

更多信息

关于搜索API的更多信息,建议观看WWDC的Session 709:《Introducing Search APIs》。也可以阅读《NSUserActivity Class Reference》和《CoreSpotlight文档》。本文的示例代码可以在Github获取到。

戴维营教育

戴维营教育(Dive In Education),潜心做IT职业教育!紧跟时代潮流,不弄虚作假!不忘初心!

  • 官网:戴维营教育http://www.diveinedu.com
  • 在线视频:戴维营学院http://v.diveinedu.com
  • 问答网:潜心俱乐部http://divein.club

你可能感兴趣的:(iOS 9: Day by Day 第一天 搜索API)