【iOS新技术应用之Spotlight 让搜索与app无缝衔接】

Spotlight介绍

Spotlight是iOS 9及以上版本支持的一个新特性,让开发者可以将自己应用内的任何数据放到系统全局索引中,当用户在系统的搜索框中输入关键字时,相关的内容就会被展示出来,点击结果就会跳转到相应的app中,从而提高app的日活。
【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第1张图片

搜索项展示的元素:

【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第2张图片

使用场景

当用户升级到iOS9系统以后,出现了下面的使用场景:

  • 用户手机上安装的app数量达到上百个时,他突然想要查看一个具体的内容,但他不记得在哪个app上查看过。这时候,如果他只搜索他记得的关键字,然后点击对应的条目,直接跳转到他想要访问的app的具体页面。
  • 用户突然想要在网上买一双鞋子,没有很好的选择,希望看看其他用户都去哪里买,通过Search入口,她很快的就搜索到对应的排名靠前网页。

如何让你的app可以被搜索到?

提供了三个维度让搜索和app内容无缝衔接:

【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第3张图片

NSUserActivity

NSUserActivity的索引项是通过NSUserActivity类来实现的,可以索引到用户某个已经浏览过的内容,可以实现从搜索到选中时恢复该活动。

self.activity = [[NSUserActivity alloc] initWithActivityType:@"com.xxx.xxx.xxx"];
self.activity.userInfo = @{@"title": @""};
self.activity.title = @"";
self.activity.keywords = [NSSet setWithObjects:@"", @"", @"", nil];
self.activity.eligibleForHandoff = NO;
self.activity.eligibleForSearch = YES;
[self.activity becomeCurrent];

代码解析:

  • 首先使用id创建一个NSUserActivity实例;
  • 为该对象的userInfo字典属性赋值,该属性在点击搜索结果恢复应用状态的时候会用到;
  • 设置title属性,该属性会显示在搜索结果中;
  • 设置keywords属性,搜索关键字;
  • eligibleForHandoff属性表示该activity是否可用于Handoff功能;
  • eligibleForSearch属性表示该activity是否会出现在搜索结果中;
  • 最后调用becomeCurrent方法,这个activity就会被自动添加到设备索引中,可以在Spotlight中搜索到了。

【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第4张图片

用户点击搜索结果时恢复应用状态

- (BOOL)application:(UIApplication *)application 
        continueUserActivity:(NSUserActivity *)userActivity                             
        restorationHandler:(void (^)(NSArray * _Nullable))restorationHandler
{
    // restore your app state with userActivity.
    return YES;
}

Note:声明NSUserActivity时,必须是一个全局的,不能是局部的,否则搜索不到结果。

CoreSpotlight

索引项是CSSearchableItem,添加到app代码中,可以索引到任何app内容。

NSMutableArray *searchableItems = [NSMutableArray array];
for (TestEntity *entity in self.questionList) {
    CSSearchableItemAttributeSet *attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(__bridge NSString *)kUTTypeImage];
    attributeSet.title = entity.displayName;
    attributeSet.contentDescription = entity.question;
    attributeSet.thumbnailData = [NSData dataWithContentsOfURL:[NSURL  URLWithString:entity.avatar]];
    attributeSet.keywords = @[@"产品", @"运营", @"市场"];
    CSSearchableItem *searchableItem = [[CSSearchableItem alloc] initWithUniqueIdentifier:entity.userId domainIdentifier:@"com.xxx.xxx.xxx" attributeSet:attributeSet];
   [searchableItems addObject:searchableItem];
}

[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:searchableItems 
completionHandler:^(NSError * _Nullable error) {
    if (error) {
    } else {
    }
}];

代码解析:

  • 创建一个数组searchableItems,用于保存要被索引的数据;
  • 遍历所有数据,根据实体数据创建CSSearchableItem对象,然后将该对象添加到到数组searchableItems中;
  • 针对每个搜索对象,首先需要创建一个CSSearchableItemAttributeSet对象attributeSet,因为我们要显示搜索缩略图,所以将itemContentType设为kUTTypeImage;
  • 然后设置attributeSet对象的属性,title、contentDescription、thumbnailData、keywords等,其中前三个会出现在搜索结果中;
  • 然后根据attributeSet对象创建CSSearchableItem类的对象,参数uniqueIdentifier是每个搜索条目唯一的ID;
  • 最后使用CSSearchableIndex类将可搜索条目添加到设备索引中,用于Spotlight搜索;

【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第5张图片

响应用户点击搜索结果,跳转到APP的指定页面

当用户点击搜索结果条目时,会跳转到对应的应用,我们需要在应用中显示搜索结果的详细信息。实现方式是实现AppDedelegate中的回调方法:

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)
userActivity restorationHandler:(void(^)(NSArray * __nullable restorableObjects))
restorationHandler {
    NSString *itemID = [userActivity.userInfo objectForKey:CSSearchableItemActivityIdentifier];
    // 根据itemID跳转到相应界面
    return YES;
}

Note:使用CoreSpotlight framework只能将APP内容添加到设备索引中,只能在当前设备搜索,其他设备无法搜索到。要想让你的应用内容被所有用户搜索到,需要用到下面的Web markup。

Web markup

如果你的应用有对应的网站,可以对网站按照苹果的文档做一些适配,这样苹果的搜索引擎就可以对你的网站进行索引,并将搜索结果和你的应用关联起来。如果你的应用已经安装了,用户点击搜索结果可以自动跳转到你的应用相应的页面;如果你的应用还没有被安装,用户点击搜索结果可以跳转到AppStore引导用户安装你的应用。
官方文档:
https://developer.apple.com/library/content/documentation/General/Conceptual/AppSearch/WebContent.html
但是不幸的是,该功能目前只支持部分国家,还不支持中国。

【iOS新技术应用之Spotlight 让搜索与app无缝衔接】_第6张图片

搜索索引管理API

我们应该在搜索条目不需要的时候将其从设备索引中删除,CSSearchableIndex类提供了3个删除设备索引的方法。

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

动态配置搜索条目

  • 配置下发更新搜索条目(增删改);
// xxx配置中心 配置样例如下:
{
"xxxSearchableItems": [
    {
        "title": "",
        "contentDescription": "",
        "thumbnailUrl": "",
        "actionUrl": ""
    },
    {
        "title": "",
        "contentDescription": "",
        "thumbnailUrl": "",
        "actionUrl": ""
    }
],
    "RemoveAll": "NO",
    "RemoveDomainItems": [
        "com.baidu.consult.x",
        "com.baidu.consult.xx",
        "com.baidu.consult.xxx"
    ]
}

决定搜索结果排名的几个因素

  • 用户查看内容的频率(只通过NSUserActivity的使用来捕获)。
  • 用户参与你的内容的数量,表现在用户点击搜索结果或发现有用信息时。
  • 在标记网页内容的时候,URL的普及和可用的结构化数据的数量。

如果做到以下几点,也会鼓励用户来使用你的app:

  • app中具有引人注目的内容。
  • 通过使用搜索相关的API来提高搜索结果的关联性。
  • 尽可能只索引用户最可能搜索的项目。
  • 在必要时删除和更新索引项目,使搜索保持最新状态。
  • 通过提供贴切的、丰富的索引项目来鼓励用户与之建立联系。
  • 最小化搜索结果的点击时间和查看应用程序内容的时间。

你可能感兴趣的:(Objective-C)