金田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. motan源码分析二:使用spi机制进行类加载

    在motan的源码中使用了很多的spi机制进行对象的创建,下面我们来具体分析一下它的实现方法. 1.在实际的jar包的\META-INF\services目录中引入相关的文件,例如下图中,我解压了co ...

  2. Ubuntu 13.04编译boost1.54

    因为要用基于GCC4.8.1的boost最新版本的库,默认apt-get install 安装的是boost1.53, 并且基于GCC4.7.3,不是我想要的.所以决定下载源代码自己编译. 下载(后面 ...

  3. Robotium API -- 判断测试结果的方法assert、is、search

    下面的这些方法都主要用来判断测试结果是否与预期结果相符,一般把is和search方法放在assert里面判断.assert最常用的还是assertThat方法,是Junit的判断,这里就不多说了. 断 ...

  4. java环境下的数据库读写分离

    方案很多:阿里的中间件cobar.aop注解方式.com.mysql.jdbc.ReplicationDriver读写分离驱动MySQL数据库的同步. MySQL是开源的关系型数据库系统.主从同步复制 ...

  5. SVN经常使用命令说明

    SVN版本号:1.5 及更新版本号 名词说明: WC:Working Copy 你的工作区 Versioned:受控的:受版本号控制的 SVN是什么? SVN是开源的版本号控制系统. 比CVS很多其它 ...

  6. AMD 规范以及如何将AMD转变为CommonJS

    原文:http://villadora.me/2014/05/23/amd-define-and-how-to-translate-amd-to-commonjs/ CommonJS和AMD的争论已经 ...

  7. android使用微软EWS发送邮件

    通常我们在android使用javamail发送邮件,可是很多时候我们需要连接Exchange服务(很多公司内部邮件服务器采用,并且未开通smtp服务)来发送邮件,这时候我们就要用到微软的 ews-j ...

  8. 95秀-自定义对话框 dialog 合集

    普通的确认对话框 NormalDialog.java import android.app.Dialog; import android.content.Context; import android ...

  9. bzoj 3043 (差分序列运用)

    维护差分序列 显然要使差分序列的后n-1位为0 对于原来的区间操作 只需要单点修改或者两个点修改 就转化成了 对于差分序列但以一个数+ 或 - 或者一个+1同时一个- ans1=max(sum1,su ...

  10. MyKTV项目,走起!

    MyKTV项目,走起! 第一部分:这个项目对于新手来说有一点难度,但是当你理清类之间的关系和怎样去实现功能后就会感觉轻松很多. 话不多说,先上类图: 接着是数据库表间关系: 本项目要实现以下功能: 明 ...