iOS9 SpotLight新功能(1)

iOS9推出后,为了顺应时代,给自己项目加了个Spotlight搜索功能,下面是使用过程中的一点记录

在iOS9中提供了新的APIs,允许你去索引APP里面的内容或者界面状态,通过Spotlight来快速显示APP中的内容。 这些新的搜索APIs的三大组件为:

  • NSUserActivity (iOS8 出现的类,提供handoff功能支持)
  • Core Spotlight (新库,提供Spotlight索引APP内容的功能)
  • web markup(鬼知道什么东西,看名字不像APP开发用的)

1、NSUserActivity

最开始NSUserActivity是iOS8的新特性:HandOff功能所使用的API,用于保存和复原APP的状态。由于项目对HandOff并没啥友好性,所以去年也没有太多的研究,顺道学习一下。
学习链接

简单的说,使用NSUserActivity主要有以下几点:

  • unique identifier(唯一的标识符,通过此标识符,可以链接不同设备的同一APP,也是能实现HandOff功能的基础)
 <key>NSUserActivityTypes</key>
 <array>
  <string>com.xxx.iOS-9-Search.displayShow</string>
 </array>
  • 保存一个UserActivity
NSUserActivity * activity = [[NSUserActivity alloc] initWithActivityType:@"com.xxx.iOS-9-Search.displayShow"];
        
activity.title = @"test";
activity.userInfo = [NSDictionary dictionaryWithObjectsAndKeys:item.name, @"name", item.id, @"id", nil];
        
[activity becomeCurrent];
  • 恢复restore
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
  • update UserActivity
[activity addUserInfoEntriesFromDictionary:dic];

上面4点是NSUserActivity使用过程中需要用到的主要情景。实例化的NSUserActivity对象,可以通过属性retain住,根据情况调用update方法,更新userActivity的userInfo(dictionary)

  • 其他
    eligibleForHandoff,eligibleForSearch:两个属性,区分HandOff和SpotLight。

    expirationDate:当这个属性被设置时,你的user activity 只会在设置的时期之前才会展示在搜索结果里。
    

2、Core Spotlight

当然,先导入最新的库CoreSpotlight.framework
使用起来非常简单,通常在获取网络数据返回后,讲获得数据item,添加到searchIndex中。

    NSMutableArray *items = [NSMutableArray array];
    for (likeItem *item in self.Model.likeItems) {
        CSSearchableItemAttributeSet * attrSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:@"text"];
        NSString *title = item.forumName;
        [attrSet setTitle:title];
        NSString *desc = [NSString stringWithFormat:@"bar"];
        [attrSet setContentDescription:desc];
        CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:item.uniqueIdentifier domainIdentifier:@"like items" attributeSet:attrSet];
        [items addObject:item];
    }
    [[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:items completionHandler:^(NSError * _Nullable error) {
        
    }];

添加完搜索索引以后,与userActivity相同,通过spotLight搜索到的内容,点击需要跳转到我们自己的app中,并能够跳转到对应的界面。


- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    UITabBarController *tabBarController = (UITabBarController *)[self getTabBarController];
    UIViewController *vc = [tabBarController viewControllerAtIndex:0];
    [vc restoreUserActivityState:userActivity];
    return YES;
}

3、NSUserActivity与Spotlight相结合

在iOS9中NSUserActivity类的新增特性就是contentAttributeSet属性。这个属性允许你赋予一个CSSearchableItemAttributeSet, 正如你先前创建的那个。这个属性集合(attribute set)允许NSUserActivity对象的搜索结果可以展示如同 Core Spotlight搜索结果那样的相同数量的详细信息。

但是,在尝试两者结合时,遇到了一些问题,首先,activity中构造的userInfo字典不能够搜索完了restore,userInfo中只包涵一个key:(妈蛋,为啥上不了图)

  kCSSearchableItemActivityIdentifier

这个key从哪来的呢?

     CSSearchableItem *item = [[CSSearchableItem alloc] initWithUniqueIdentifier:item.uniqueIdentifier domainIdentifier:@"like items" attributeSet:attrSet];

就是这句话,kCSSearchableItemActivityIdentifier的Value就是CSSearchableItem初始化时,传入的参数uniqueIdentifier

再看下文档里怎么说:

// When opening a document from Spotlight, the application's application:willContinueUserActivityWithType:
// method will get called with CSSearchableItemActionType, followed by  application:continueUserActivity:restorationHandler: with an NSUserActivity where the userInfo dictionary has a single key value pair where CSSearchableItemActivityIdentifier is the key and the value is the uniqueIdentifier used when creating the item.
CORESPOTLIGHT_EXPORT NSString * const CSSearchableItemActionType CS_AVAILABLE(NA, 9_0);
CORESPOTLIGHT_EXPORT NSString * const CSSearchableItemActivityIdentifier CS_AVAILABLE(NA, 9_0);

CS_CLASS_AVAILABLE(NA, 9_0)
@interface CSSearchableItem : NSObject <NSSecureCoding, NSCopying>

- (instancetype)initWithUniqueIdentifier:(nullable NSString *)uniqueIdentifier //Can be null, one will be generated
                        domainIdentifier:(nullable NSString *)domainIdentifier
                            attributeSet:(CSSearchableItemAttributeSet *)attributeSet;

// Should be unique to your application group.
// REQUIRED since this is the way you will refer to the item to update the index / delete it from the index
// Starts with an UUID for ease of use, but you can replace it with an UID of your own before the item is first indexed if you wish.
@property (copy) NSString *uniqueIdentifier;

英文不好也能看懂,关键的方法:
application:willContinueUserActivityWithType:
会自动生成一个NSUserActivity对象,该对象的userInfo中只有一个Key,也就是上面看到的那个key。而对应的value就是在初始化CSSearchableItem时,传入的参数,相对于你的app,它必须是唯一的,同时,你可以传一个nil,但是,app会自动给你生成一个唯一的,作为restore时的唯一标识。

由此可见可以在CSSearchableItem初始化时,控制传入的参数,达到自己目的。比如,在我的项目中,我希望可以搜索两种信息,简单的说就是希望可以判断搜索内容的类型,并根据该类型跳转到对应ViewController,我是用的方法就是通过传入的uniqueIdentifier来做判断,进而根据其他参数初始化ViewController,跳转到该vc。

这样做挺low的,但是确实实现了我的需求,想来苹果不会搞出这么low的方法,先这样,等下篇文章(2)中,在对实现这个小需求中遇到的问题做进一步的探索,对NSUserActivity与Spotlight的结合问题再搞搞,搞清楚点,特别是那个userinfo字典,到底啥机制,好像初始化了没啥卵用哦,就为了多点信息?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容