在 iOS 9 之前,用户只能通过 Spotlight 搜索有限的基本内容,诸如备忘录、短信等,而从 iOS 9 开始,苹果允许用户搜索活动、App 状态、App 内容甚至未安装的 App 信息,也就是这篇博客要介绍的内容—— Search API。
关于其他 iOS 9 的特性与功能,有兴趣的朋友可以参考我博客中的 iOS 9 适配系列。
我们所说的 Search API 共分为三种:
-
NSUserActivity -
Web Markup -
CoreSpotlight
本文主要介绍 CoreSpotlight 的基本使用(点击这里直接跳转),另外两种由于比较简单,因此只做基本概念阐述。
NSUserActivity
使用过 Handoff 功能的小伙伴们可能对 NSUserActivity 比较熟悉,因为这在 iOS 8 中专为 Handoff 推出的 API。
而在 iOS 9 中 NSUserActivity 的功能得到了显著提升,简单来说,从 iOS 9 开始用户只要在 Spotlight 中提供元数据(Metadata)即可搜索不同的 Activity(活动)。
Web Markup
Web Markup 是 iOS 9 新推出的功能,它用于在网页中显示 App 内容并编入 Spotlight 索引,也就是说即使用户并没有安装某个 App,iOS 9 也可以在网页上搜索特定标记(Markup)并在 Safari 或 Spotlight 中显示搜索结果。
如果你有兴趣你可以参考官方文档 Use Web Markup to Make App Content Searchable。
CoreSpotlight
从名字就能看出 CoreSpotlight 是一套完整的 Spotlight 框架,它允许开发者将 App 中的任意内容编入索引使得这些内容可以在 Spotlight 相关搜索结果中显示,提供更好的用户体验。
与 NSUserDefault 不同,CoreSpotlight 使用系统的存储空间,它存储的内容称为 CSSearchableItem,我们可以通过 CSSearchableItemAttributeSet 为每个 CSSearchableItem 设置属性。
要使用 CoreSpotlight,首先需要引入 CoreSpotlight.framework (在 Target => Build Phases => Link Binary With Libraries 中添加)并导入头文件:
import CoreSpotlight
接下来创建 CSSearchableItemAttributeSet 和 CSSearchableItem:
let identi = "meniny"
let attrSet = CSSearchableItemAttributeSet(itemContentType: "someType")
attrSet.title = identi
attrSet.contentDescription = "Some Description Here"
attrSet.thumbnailData = UIImageJPEGRepresentation(UIImage(named: "icon_Image")!, 0.5)
let item = CSSearchableItem(uniqueIdentifier: identi, domainIdentifier: "cn.meniny.MXSearchAPIDemo", attributeSet: attrSet)
调用 CSSearchableIndex.defaultSearchableIndex() 的 indexSearchableItems(items: [CSSearchableItem], completionHandler: ((NSError?) -> Void)?) 方法将内容编入索引:
CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([item], completionHandler: { (error) -> Void in
if error == nil {
print("saved")
}
})
最后,当用户点击搜索结果后,系统会自动跳转到我们的应用,因此我们需要在 AppDelegate 中 application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool 方法编写跳转后的相关逻辑:
func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool {
let identifier = userActivity.userInfo?["kCSSearchableItemActivityIdentifier"] as? String
let nav = window?.rootViewController as! UINavigationController
nav.popToRootViewControllerAnimated(false)
let newVC = UIViewController()
newVC.title = identifier
newVC.view.backgroundColor = UIColor.whiteColor()
nav.pushViewController(newVC, animated: true)
return true
}
此外,CoreSpotlight 还提供了三种删除索引的方法,分别是:
-
deleteSearchableItemsWithIdentifiers(identifiers: [String], completionHandler: ((NSError?) -> Void)?),根据identifiers: [String]删除 -
deleteSearchableItemsWithDomainIdentifiers(domainIdentifiers: [String], completionHandler: ((NSError?) -> Void)?),根据domainIdentifiers: [String]删除 -
deleteAllSearchableItemsWithCompletionHandler(completionHandler: ((NSError?) -> Void)?),删除全部
这三种方法通过单例 CSSearchableIndex.defaultSearchableIndex() 调用即可,十分简单不做赘述。