IOS实现APP支持SpotLight搜索

来源:互联网 发布:若风外设淘宝店地址 编辑:程序博客网 时间:2024/06/10 19:08

#import <CoreSpotlight/CoreSpotlight.h>  

CoreSpotlight.framework


参考:http://blog.csdn.net/a416863220/article/details/51220375;
参考:http://blog.csdn.net/chenyong05314/article/details/49491595;
参考:http://www.cnblogs.com/CocoonJin/p/4703366.html
坑:http://blog.csdn.net/longitachi/article/details/50218147
======iOS9 有三中方法实现搜索=====

NSUserActivity(参考:http://www.jianshu.com/p/2ec61e2c00cb)

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

@interface LilithViewController ()

// 注意:必须是强引用

@property (nonatomic, strong)NSUserActivity *activity;

@end


@implementation LilithViewController


- (void)viewDidLoad {

    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    self.navigationItem.title =@"Lilith";

    [selfaddUserActivity];

    

}

- (void)addUserActivity{

    

    // 使用唯一标识符 @"lilith"创建一个新的NSUserActivity对象

    // 这个工程已经被配置成确保使用这个标识符时要保证它不会被改变

    _activity = [[NSUserActivity alloc]initWithActivityType:@"lilith"];

    

    // 这就是将会在Spotlight搜索结果里出现的内容

    _activity.title = @"Lilith";

    

    // 搜索的关键字

    // 为了确保可搜寻的内容不仅止限于应用的标题,你也要提供一系列的关键字

    _activity.keywords = [NSSet setWithArray:@[@"Lilith"]];

    

    // 是否将用户活动转交到其他设备

    _activity.eligibleForHandoff = NO;

    

    // 是否显示历史搜索记录

    _activity.eligibleForSearch = YES;

    

    // 它自动的被加入到了设备的搜索结果索引中

    [_activity becomeCurrent];

    

    // 过期时间,比如新闻一周后就过期

    // _activity.expirationDate =

    

    // 每个控制器的user activity搜索结果都是仅当应用曾经被打开过时而创建的

    // _activity.eligibleForPublicIndexing = YES;


[_activity becomeCurrent];


}

********************

AppDelegate方法中监听Spotlight中的点击


- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray *_Nullable))restorationHandler

{

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

    [navi.topViewControllerrestoreUserActivityState:userActivity];

    

    returnYES;

}

ViewController中实现跳转

- (void)restoreUserActivityState:(NSUserActivity *)activity{

    if ([activity.titleisEqualToString:@"Adam"]) {

        AdamViewController *adamView = [[AdamViewControlleralloc]init];

        [self.navigationController pushViewController:adamView animated:YES];

    }elseif([activity.titleisEqualToString:@"Lilith"]){

        LilithViewController *lilithView = [[LilithViewControlleralloc]init];

        [self.navigationController pushViewController:lilithView animated:YES];

    }else if([activity.titleisEqualToString:@"Eve"]){

        EveViewController *eveView = [[EveViewControlleralloc]init];

        [self.navigationController pushViewController:eveView animated:YES];

    }

}

====================

Web Markup

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

Core Spotlight

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


============spotlight实现搜索=======
======实现例子一:

- (void)saveData{

    NSMutableArray *seachableItems = [NSMutableArraynew];

    [self.titleArrenumerateObjectsUsingBlock:^(NSString *__nonnull obj,NSUInteger idx, BOOL *__nonnull stop) {

         /*创建属相集合,应用内搜索,想搜索到多少个界面就要创建多少个set,每个set都要对应一个item*/

        CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSetalloc] initWithItemContentType:@"views"];//ContentType就是做一个标记

        attributeSet.title = obj;//主标题

        attributeSet.contentDescription = [NSStringstringWithFormat:NSLocalizedString(@"spotlight测试 %@", nil),obj];//详细标题

          attributeSet.contactKeywords = @[@"自己做的",@"obj02",@"obj03"];//搜索关键字

        

        //设置图片----可以通过data设置,可以通过url设置

        UIImage *thumbImage = [UIImageimageNamed:@"tg"];//缩略图

        

        attributeSet.thumbnailData =UIImagePNGRepresentation(thumbImage);

        

        //这里的url也必须是本地文件路径,而不是网络图片url

        //    firstSet.thumbnailURL = [NSURL URLWithString:@"http://www."];

        

        //一个条目中的属性集合和搜索的唯一标示UniqueIdentifier和删除的唯一标识domainIdentifier绑定。UniqueIdentifier每个搜索都有一个唯一标示,当用户点击搜索到得某个内容的时候,系统会调用代理方法,会将这个唯一标示传给你,以便让你确定是点击了哪一,方便做页面跳转

        //domainIdentifier搜索域标识,删除条目的时候调用的delegate会传过来这个值

        CSSearchableItem *item = [[CSSearchableItemalloc] initWithUniqueIdentifier:obj                                                                                                                                                                                                                                     domainIdentifier:@"com.kdanmobile.CoreSpotlightDemo"                                                                                                                                                                                 attributeSet:attributeSet];

        

        [seachableItems addObject:item];//条目集合

        

    }];

    

    //吧条目集合添加上索引

    [[CSSearchableIndexdefaultSearchableIndex] indexSearchableItems:seachableItems

            completionHandler:^(NSError *__nullable error) {

                            if (!error)

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

                

            }];

    

}   


=======实现例子二:

- (void)setupSpotlight

{

    if ([UIDevicecurrentDevice].systemVersion.floatValue < 9.0) {

        return;

    }

    

    //搜索的时候是根据title(主标题),contentDescription(副标题),contactKeywords(关键字集合),来搜索的。

    /*应用内搜索,想搜索到多少个界面就要创建多少个set,每个set都要对应一个item*/

    CSSearchableItemAttributeSet *firstSet = [[CSSearchableItemAttributeSetalloc]initWithItemContentType:@"第一"];

    //标题

    firstSet.title =@"one";

    //详细描述

    firstSet.contentDescription =@"第一个";

    //关键字

    firstSet.contactKeywords = @[@"first",@"测试",@"firstView"];

    //设置图片

    //这里的url也必须是本地文件路径,而不是网络图片url

    //    firstSet.thumbnailURL = [NSURL URLWithString:@"http://www."];

    //也可以用这个图片加载方法

    firstSet.thumbnailData =UIImagePNGRepresentation([UIImageimageNamed:@"tg"]);

    /*

     这里有个小细节:

     设置的图片展示的效果系统并不会给你处理,意思是说,如果你传了一张长方形的图片做封面icon,你在搜索列表上展示的icon就是长方形的,如果长宽比很大的话,很很难看,所以这里尽量保证图片趋近去正方形,使得展示效果好看点。

     或者在自己裁剪处理下趋近正方形。

     */

    

    CSSearchableItemAttributeSet *secondSet = [[CSSearchableItemAttributeSetalloc]initWithItemContentType:@"第二"];

    secondSet.title =@"two";

    secondSet.contentDescription =@"第二个";

    secondSet.contactKeywords = @[@"second",@"测试",@"secondView"];

    secondSet.thumbnailData =UIImagePNGRepresentation([UIImageimageNamed:@"lczq"]);

    

    //一个条目中的属性集合和搜索的唯一标示UniqueIdentifier和删除的唯一标识domainIdentifier绑定。UniqueIdentifier每个搜索都有一个唯一标示,当用户点击搜索到得某个内容的时候,系统会调用代理方法,会将这个唯一标示传给你,以便让你确定是点击了哪一,方便做页面跳转

    //domainIdentifier搜索域标识,删除条目的时候调用的delegate会传过来这个值

    CSSearchableItem *firstItem = [[CSSearchableItemalloc] initWithUniqueIdentifier:@"firstItem"domainIdentifier:@"first"attributeSet:firstSet];

    

    CSSearchableItem *secondItem = [[CSSearchableItemalloc] initWithUniqueIdentifier:@"secondItem"domainIdentifier:@"second"attributeSet:secondSet];

    

    NSArray *items = @[firstItem,secondItem];

    

    //把上面的设置item都添加进入

    [[CSSearchableIndexdefaultSearchableIndex] indexSearchableItems:items completionHandler:^(NSError *_Nullable error) {

        if (error) {

            NSLog(@"失败%@",error);

        }

        else {

            NSLog(@"成功");

        }

    }];

}



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

//在APPdelegate中实现这个方法

//点击搜索到的结果,会自动掉用下面的方法,根据搜索标识跳转到相应界面

- (BOOL)application:(nonnullUIApplication *)application continueUserActivity:(nonnullNSUserActivity *)userActivity restorationHandler:(nonnullvoid (^)(NSArray *__nullable))restorationHandler{

    

    //获取点击的搜索唯一标识

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

    

    

    UIViewController *VC =self.window.rootViewController;

    if([identifierisEqualToString:@"firstItem"]){

        [VC presentViewController:[[OneVCalloc]init]animated:YEScompletion:nil];

    

    }elseif([identifier isEqualToString:@"secondItem"]){

    [VC presentViewController:[[TwoVCalloc]init]animated:YEScompletion:nil];

    }

  

    

    returnYES;

    

====删除的方法=========

我们有时候并不是创建完Spotlight索引就没其他事了,可能会在用户的账号退出的时候去对索引进行一个清除,及换账号时候的重建,这时候我们会用到删除索引的功能,apple提供给我们三个方法去:

- (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{

    //删除所有的条目

}