iOS 9之应用内搜索(CoreSpotlight)API

金田github 示例源码

前言

       在iOS9之前我们只能使用Spotlight来搜索应用名称来打开指定App,而其他的内容都是提供给系统使用(信息,联系人,邮件等)。在iOS9以后Apple允许开发者设置应用中任意内容可以被Spotlight索引到以及用户在选择了搜索内容时会发生什么。如demo所示:

图1 Spotlight搜索应用内结果示意图

 

简单介绍

在iOS9中提供了三种API来帮助我们实现搜索,如下:

图2 iOS 9新增搜索API

NSUserActivity

NSUserActivity包含了一些新的方法和属性来帮助我们实现索引activities和应用状态使他们在搜索结果中可用。每一个应用都可以利用NSUserActivity API来生成对于用户来说更有用的内容。顺便提一句NSUserActivity在iOS8中的Handoff就已经被引入了。

Web Markup

这一特性允许应用镜像自己的内容,并在Spotlight中建立自己的引用。苹果的爬虫会抓取你的网站上打了markup的内容,而这些内容会提供给Safari和Spotlight。这个特性的神奇之处在于。用户不需要将你的应用安装在手机上。这样你的应用可以更多的展示给潜在用户。苹果的云服务会索引你的内容,让你的应用与Public Search API保持深度的链接会让你收益颇多。

Core Spotlight

新的CoreSpotlight(framework)是iOS9提供的一组新的API来帮助你建立起你的应用中的索引。CoreSpotlight是用来处理用户数据的比如:文档,照片以及其他类型的由用户产生的内容。

 

让我们开始吧

准备工作

首先我们使用三个不同的ViewController来加载不同的用户数据:

  • Image
  • TXT
  • Web

然后使用一个TableView用来索引他们这一部分的代码就不赘述具体结构如图

图3 Demo 初始化

图4 iPhone  Demo截图

好,万事具备,只欠CoreSpotlight啦

CoreSpotlight

先将framework导入
工程->Build Phases->Link Binary With Libraries->搜索CoreSpotlight
如果搜索不到请确认自己使用的是Xcode7

图 5 添加CoreSpotlight框架

 

接下来就是最重要的代码部分了

首先,导入头文件

#import <CoreSpotlight/CoreSpotlight.h> 

然后将需要索引的数据保存至CoreSpotlight

- (void)saveData{   
  NSMutableArray *seachableItems = [NSMutableArray new];   
  [self.tableData enumerateObjectsUsingBlock:^(NSString *__nonnull obj, NSUInteger idx, BOOL * __nonnull stop) {       
  CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"views"];       
  attributeSet.title = obj;     
    attributeSet.contentDescription = [NSString stringWithFormat:NSLocalizedString(@"a easy way to open %@", nil),obj]; 
        UIImage *thumbImage = [UIImage imageNamed:[NSString stringWithFormat:@"icon_%@.png",obj]];
         attributeSet.thumbnailData = UIImagePNGRepresentation(thumbImage);//beta 1 there is a bug 
         CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:obj                                                                 domainIdentifier:@"com.kdanmobile.CoreSpotlightDemo"                                                                    attributeSet:attributeSet];
         [seachableItems addObject:item];    
}];
      [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:seachableItems
                                                  completionHandler:^(NSError * __nullable error) {   
                if (!error)                                                        

 NSLog(@"%@",error.localizedDescription);                                               
  }];
}  

执行下程序然后到Spotlight查看是否有保存进去

 

如果没保存进去不要紧,尝试重启下模拟器再到Spotlight中查看应该就有了。这应该事Xcode的一个bug
另外关于CSSearchableItemAttributeSet的各个属性的含义如下图所示

图 6 Demo Spotlight搜索示意图

现在我们点击搜索到相应的项还只能打开我们的应用,如果要实现跳转还需要进行一小步的工作:在AppDelegate中实现

 

- (BOOL)application:(nonnull UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray * __nullable))restorationHandler{

     NSString *idetifier = userActivity.userInfo[@"kCSSearchableItemActivityIdentifier"];

     UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;

     [navigationController popToRootViewControllerAnimated:YES];

     CoreSpotlightTableViewController *coreViewController = [[navigationController viewControllers] firstObject];

     [coreViewController showViewControllerWithIdentifier:idetifier];

     return YES;

而在实现这个方法后在点击spotlight中点击相应的项就会跳转到我们相应的ViewController中啦

图7 Demo Spolight 搜索截图

最后需要提到的就是索引的删除。CoreSpotlight给我们提供了三个方法来进行删除分别是:


- (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来删除以及删除所有的索引。
从Xcode7自动补全的代码看来出现了很多以前不常见的代码如:nonnull , __nullable,NSArray<NSString *>,等,其中nonull在Xcode6的某个版本往后就提供了。目的是用来更好的与swift中的optional变量连接。从这些看来以后苹果的重心将慢慢往swift转移。

 

版权所有,转载须注明作者(金田)及原文出处(原文)。

posted @ 2015-08-04 22:42  CocoonJin  阅读(3528)  评论(1编辑  收藏  举报