美文网首页程序员iOS DeveloperiOS Tips
iOS9 SpotLight新功能(1)

iOS9 SpotLight新功能(1)

作者: 花落似雪 | 来源:发表于2015-09-30 14:02 被阅读936次

    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字典,到底啥机制,好像初始化了没啥卵用哦,就为了多点信息?

    相关文章

      网友评论

        本文标题:iOS9 SpotLight新功能(1)

        本文链接:https://www.haomeiwen.com/subject/vmzwcttx.html