金田(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转移。

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

iOS 9之应用内搜索(CoreSpotlight)API的更多相关文章

  1. 百度站内搜索https不可用切换api搜索,加上谷歌api站内搜索

    google推https几年了,百度开始宣传全面https,但是,百度站内搜索 自己的服务却不走https,接口报错.百度分享也是. 然后采用http://search.zhoulujun.cn/cs ...

  2. 通过Google Custom Search API 进行站内搜索

    今天突然想把博客的搜索改为google的站内搜索,印象中google adsense中好像提高这个站内搜索的代码,但苦逼的是google adsense帐号一直审核不通过,所以只能通过google c ...

  3. 基于lucene.net 和ICTCLAS2014的站内搜索的实现1

    Lucene.net是一个搜索引擎的框架,它自身并不能实现搜索.须要我们自己在当中实现索引的建立,索引的查找.全部这些都是依据它自身提供的API来实现.Lucene.net本身是基于java的,可是经 ...

  4. Lucene系列六:Lucene搜索详解(Lucene搜索流程详解、搜索核心API详解、基本查询详解、QueryParser详解)

    一.搜索流程详解 1. 先看一下Lucene的架构图 由图可知搜索的过程如下: 用户输入搜索的关键字.对关键字进行分词.根据分词结果去索引库里面找到对应的文章id.根据文章id找到对应的文章 2. L ...

  5. 使用 Elasticsearch 实现博客站内搜索

    Reference:  http://www.open-open.com/lib/view/open1452046497511.html 一直以来,为了优化本博客站内搜索效果和速度,我使用 bing ...

  6. es站内站内搜索笔记(一)

    es站内站内搜索笔记(一) 第一节: 概述 使用elasticsearch进行网站搜索,es是当下最流行的分布式的搜索引擎及大数据分析的中间件,搜房网的主要功能:强大的搜索框,与百度地图相结合,实现地 ...

  7. ElasticSearch入门-搜索(java api)

    ElasticSearch入门-搜索(java api) package com.qlyd.searchhelper; import java.util.Map; import net.sf.json ...

  8. 一步步开发自己的博客 .NET版(5、Lucenne.Net 和 必应站内搜索)

    前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做 ...

  9. 利用Solr服务建立的站内搜索雏形---solr1

    最近看完nutch后总感觉像好好捯饬下solr,上次看到老大给我展现了下站内搜索我便久久不能忘怀.总觉着之前搭建的nutch配上solr还是有点呆板,在nutch爬取的时候就建立索引到solr服务下, ...

随机推荐

  1. rman catalog (rman 恢复目录)

    受控制文件大小的限制,一般rman需要用rman catalog来管理及存放备份信息: 这里介绍一下创建rman catalog的步骤: C:\Documents andSettings\Admini ...

  2. 单页面应用SPA架构

    个人认为单页面应用的优势相当明显: 前后端职责分离,架构清晰:前端进行交互逻辑,后端负责数据处理. 前后端单独开发.单独测试. 良好的交互体验,前端进行的是局部渲染.避免了不必要的跳转和重复渲染. 当 ...

  3. apktool的下载地址

    googlecode将要关闭,代码转移到以下网址 http://ibotpeaches.github.io/Apktool/

  4. mybatis 自动生成xml文件配置

    http://blog.csdn.net/techbirds_bao/article/details/9233599/

  5. Linux UDP严重丢包问题的解决

    测试系统在Linux上的性能发现丢包率极为严重,发210000条数据,丢包达110000之巨,丢包率超过50%.同等情形下Windows上测试,仅丢几条数据.形势严峻,必须解决.考虑可能是因为协议栈B ...

  6. 内存泄露 Memory Leaks

    什么是内存泄露 内存管理一直是Java 所鼓吹的强大优点.开发者只需要简单地创建对象,而Java的垃圾收集器将会自动管理内存空间的分配和释放. 但在很多情况下,事情并不那么简单,在 Java程序中总是 ...

  7. codevs 4650 破损的键盘(链表)

    /* 之前一直不重视链表 (好吧说实话主要是看着板子都是指针就怂了T.T) 这道题比较基础 应用了链表的思想 数组模拟指针 遇到的问题就是跑着跑着光标跳到前面或者跳到后面 我们用next储存每个点下一 ...

  8. linux下查看已经安装的jdk 并卸载jdk

    一.查看Jdk的安装路径: whereis javawhich java (java执行路径)echo $JAVA_HOME echo $PATH 备注:如果是windows中,可以使用: set j ...

  9. JAVA为什么会空指针异常

    1.所谓的指针,就是java中的对象的引用.比如String s;这个s就是指针. 2.所谓的空指针,就是指针的内容为空,比如上面的s,如果令它指向null,就是空指针. 3.所谓的空指针异常,就是一 ...

  10. java数据库连接类,已经把数据库操作的方法都封装好了

    在这里分享一个已经封装好了的java数据库连接类,只要创建对象就可以实现数据库的增删改查操作,用过都说好.其实这个不是我自己写的,是一个理解和学习能力超高的朋友写的,他也很乐于分享交流,本人也深受他的 ...