摘要
最近在做项目的时候,刚好有一个需求是要用到iOS9所支持的一个新特性—-CoreSpotlight 来实现,所以简单记录一下CoreSpotlight 的使用方法啦啦啦~~
什么是 Spotlight
可能大家的 iPhone 或者 iPad 在更新了iOS9 之后就会发现,在主屏幕下滑,或者最左边屏幕最右滑时,可以对整个手机里的内容进行搜索。像下面这样:
iOS9 中支持为 app 中的内容做索引以支持 spotlight 搜索,并且这些索引是存在本地设备中的,不会同步到icoloud中,更换了设备就没有了。
那我们需要在我们的代码里边做怎么样的支持才能让我们的 app 像微博、知乎一样支持 spotlight 对我们的内容进行搜索呢?
Spotlight 使用
使用前提
framework的导入
使用 Spotlight 的前提是要在项目里面导入以下两个库:
头文件的导入
1 |
前面也说过,Spotlight 只支持 iOS9以上版本,所以如果要适配 iOS9 以下的版本,记得一定要做好版本的判断语句,不管是在导入头文件的时候还是调用API的时候。如下:
1 | //code... |
使用
用豆瓣电影列表为例子,demo 可让我们在 Spotlight 里面根据电影的 分类 来搜索到我们对应的电影~
定义内容类
1 | CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeImage]; |
CSSearchableItemAttributeSet 是一个提供给 Spotlight 搜索的内容类,我们可以设置它的各种属性,用户通过 Spotlight 搜索得到的内容样式就是由它控制的;temp 是定义了一部movie基本信息的 NSDictionary.
内容类添加到索引(可供搜索类)
想供 Spotlight 搜索得到我们的数据模型,还需要将内容类添加到可供搜索的类 CSSearchableItem 。如下:
1 | CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:[NSString stringWithFormat:@"%d",i] domainIdentifier:@"Zen3.CoreSpotlightDemo" attributeSet:attributeSet]; |
其中,
UniqueIdentifier:(nullable NSString *) 是唯一标识识别是这个索引数据的,可以理解为标识符,后面可以用于判断用户点击 Spotlight 的搜索结果,是从哪一个电影索引跳入 appDemo 的。
domainIdentifier:(nullable NSString *) 是确定这个索引数据是属于哪个“范围”的,这个范围可以用来区别不同 app 的索引数据,也可以用于区别同一个app里面不同模块的索引数据。
attributeSet:(CSSearchableItemAttributeSet *) 就是我们刚刚上面定义的。
封装索引为数组并添加
将可供搜索类 CSSearchableItem 全部添加到一个数组(NSMutableArray)里面。
将包含所有索引(可供搜索类)的数组,通过以下方法提交:
1 | [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:seachableItems completionHandler:^(NSError * error) { |
完成了以上几步,你就可以通过 keyword 来搜索到你的 内容类了。那如果你想点击不同搜索结果,比如电影,进入app里面会跳转到不同的页面,你还需要做下面的事情。
不同索引不同跳转
搜索得到结果后页面的跳转实现,主要是在 AppDelegate.m 里定义的:
1 | - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler |
删除索引条目
关于删除索引,上文也有提起过,我们上面所做的添加提交索引操作都是在设备本地的,所以删除也是如此,有以下三种方法:
1 | - (void)deleteSearchableItemsWithIdentifiers:(NSArray<NSString *> *)identifiers completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler; -(void)deleteSearchableItemsWithDomainIdentifiers:(NSArray<NSString *> *)domainIdentifiers completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler; - (void)deleteAllSearchableItemsWithCompletionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler; |
分别是根据identifier来删除,根据domain来删除以及删除所有的索引。
维护好app里面所定义提交的索引是开发者的职责,对于已经失效,或者弃用的索引,一定要及时删除,避免造成不好的用户体验。
暂时还有没有找到关于索引更新的API,知道的童鞋可以赐教一下~所以我目前对索引的更新就是使用删除旧的,添加新的的方式。
一点我遇到的坑
如果用虚拟机进行调试的话,如果遇到 indexSearchableItems 提交没有报错却搜索不到,可以重启一下虚拟机;如果更改了domainIdentifier或者UniqueIdentifier的传入值,而log出来的结果还是一样,可以尝试先删除所有之后,再次重启虚拟机试一试。
我的demo
附上我的demo地址:lzcuriosity/CoreSpotlightDemo
最后
今晚写完这篇博客,我就要出现在召唤师峡谷了啦~~哈哈哈~希望今晚能一直连胜!我准备祭出我的神级机器人了!再见~