为开发人员揭秘iOS 9 Spotlight搜索

本文概述

  • 基础:CoreSpotlight框架
  • iOS 9中搜索的工作方式
  • 用户单击时
  • 概括
iOS内置了三个搜索点:Siri, Spotlight搜索和Safari搜索。 Siri是iOS最具标志性的功能之一, 是大多数iPhone用户已经熟悉的功能。但是很多人并不了解Spotlight搜索-在Siri诞生之前, 它已经成为iOS不可或缺的一部分。当你向下滑动主屏幕或者是iOS 9的新功能时, 可以从个人主屏幕向右轻扫以访问Spotlight搜索。这将在屏幕顶部显示一个搜索栏。
iOS 8及更早版本中此搜索工具的重点是搜索手机本身, 因此其结果页列出了手机上的应用程序以及Apple应用程序中的电子邮件, 消息和其他私人物品。如果它似乎相关的话, 还将显示Wikipedia定义。最后, 作为附加步骤, 它提供了通过Safari搜索网络的选项。
与Spotlight搜索相反, Safari可以在你的手机外部进行所有操作。在iOS 8中, 用户可以选择用于Safari搜索的搜索引擎:Google, Yahoo, Bing和DuckDuckGo。自然, Google会处理大多数Safari搜索请求。无论选择哪种搜索引擎, 预填的搜索词都会在Safari中显示, 并且可能与Wikipedia匹配。
为开发人员揭秘iOS 9 Spotlight搜索

文章图片
在iOS 9中, Spotlight Search比以前更加突出和广泛。实际上, 你首先看到的是基于你的使用方式的” Siri建议” 。例如, 如果你下午定期使用Safari, 那么Siri会在该时间左右为你提供建议。
而且, 尽管它仍然是查找” 手机上的事物” 的地方, 但它正成为” 手机上没有事物” 的直接门户。你已经看到附近的事物, 以及通过Apple自己的搜索引擎从网络上获取新闻头条的消息, 而其他基于网络的搜索结果现在才刚刚开始出现。
是的, Apple为iOS 9创建了一个网络搜索引擎, 这是非常重要的一步。向Applebot打个招呼。
与Spotlight相似, Apple表示对Safari的目标还在于从Apple的搜索索引中浮现结果和建议, 然后再提供与Google(或其他选定的提供商)一起搜索网络的功能。从iOS 9.1开始, Safari似乎一直在落后于Spotlight搜索, 因为它继续提供用户选择的搜索提供商的结果-可能是为了让Apple较慢地推出其搜索功能, 并有更多时间来微调其算法。
iOS 9的发布特别令人兴奋的是, 它首次使iOS开发人员能够使用这些搜索功能并在应用程序中包含内容。此外, 可以保证搜索将最终包括不在用户手机上的结果。这是一个巨大的步骤。
让我们将其放在上下文中。 Google的搜索引擎催生了围绕” SEO” 的整个行业, 这是围绕Google搜索优化资产的过程。全面推出后, Apple的搜索引擎将拥有大约50%的移动搜索市场, 占整个搜索流量的50%(并且还在不断增长)。因此, Applebot很大, 这意味着” Apple Mobile Search Optimization” 也将很大。
与常规的SEO相比, Apple Mobile Search Optimization的努力将对移动用户的应用发现产生更大的影响。
欢迎来到新兴的AMSO行业。
坏消息是, 实现所有这些功能涉及Apple的许多新技术以及对旧技术的增强, 这些元素的组合可能会造成混淆。本系列文章的目的是遍历各个部分, 并阐明如何实现它们。让我们从一些基本的东西开始, 并在此基础上。
为开发人员揭秘iOS 9 Spotlight搜索

文章图片
为了支持本系列, 我创建了一个简单的应用程序供全文参考。该项目可以在这里找到:https://github.com/rwforsythe/iOS9-Search。随着本系列继续涵盖搜索工具包的其他元素, 还将对其进行更新。
基础:CoreSpotlight框架 这个框架是iOS 9中的全新功能, 可让你将项目添加到iPhone的本地搜索索引中, 以供用户发现。例如, 在iOS 9之前, 只能通过Spotlight搜索找到Apple官方应用程序中的内容, 例如” 日历” 。现在, 通过CoreSpotlight框架发布日历事件的任何应用都可以通过Spotlight搜索甚至Siri找到。
请注意, 这里的重点是个人信息。你不希望其他手机上的用户找到你的个人日历活动!苹果公司非常清楚, CoreSpotlight框架与每个人手机上的私有索引专门交互。无法使用CoreSpotlight API在手机自己的索引之外发布内容。
这并不意味着CoreSpotlight无法用于索引已经公开的信息。当然, 可以使用CoreSpotlight从云中提取信息并将其放入手机的搜索索引中。苹果公司只是保证, 如果用CoreSpotlight为个人和机密信息编制索引, 则该信息将保持机密。
该框架分为两部分:CSSearchableItemAttributeSet对象(允许应用程序详细描述每个项目), 以及CSSearchableItem对象, 用于为项目赋予唯一的ID。每个Spotlight条目均由一对这些对象组成。使用两个对象而不是一个对象的原因是CSSearchableItemAttributeSet对象用于另一种类型的搜索交互(稍后描述)。
基础很容易。
对于那些引用示例代码的人, 可以在AppDelegate中完成CoreSpotlight的设置。
… @import CoreSpotlight; @import MobileCoreServices; …

这两个模块是新功能所必需的。
为了简化演示应用程序, application:didFinishLaunchingWithOptions:方法用于调用专用方法来设置CoreSpotlight:
if ([CSSearchableItemAttributeSet class]) [self setUpCoreSpotlight]; //Check for iOS version that supports CoreSpotlight API

向下移动到setUpCoreSpotlight方法, 我们通过创建CSSearchableItemAttributeSet对象开始该过程:
CSSearchableItemAttributeSet * attributeSet = [[CSSearchableItemAttributeSet alloc] initWithItemContentType:(NSString *)kUTTypeItem];

内容类型很重要, 因为它应该控制搜索算法处理项目的一般方式。 “ 应该” 是可操作的词, 因为这是苹果公司没有很好记录的领域。有一个大菜单项可供选择(图像类型, 视频类型, 音频类型, 联系人类型), 但是需要反复试验才能确定其对用户体验的影响(如果有)。当某些类型显示在搜索结果中时, 显示的文本内容比其他类型显示的文本内容多。它还可能影响缩略图图像是否与结果一起显示。 kUTTypeItem是一个不错的起点。
现在更详细地描述对象:
attributeSet.displayName = @"A Christmas Carol"; attributeSet.title = @"A Christmas Carol By Charles Dickens"; //Sounds similar to displayName but is not displayed to userattributeSet.contentDescription = @"Who would dare to say "Bah! Humbug" after reading A Christmas Carol? Charles Dickens wrote the novella in just six weeks before it was first published on December 19 1843 but his morality tale about a bitter old miser named Ebenezer Scrooge lives on to this day as a reminder of the importance of the Christmas spirit."; attributeSet.keywords = @[@"A Christmas Carol", @"Charles Dickens", @"Victorian Literature"]; UIImage *image = [UIImage imageNamed:@"CC-Cover"]; NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)]; attributeSet.thumbnailData = imageData;

有许多可能的属性, 特定于图像, 视频等媒体类型。更多信息可能会更好, 但是需要反复试验才能确定搜索结果中实际使用和/或显示的信息。例如, 在撰写本文时, 即使attributeSet包含星级评分数据, 似乎也不会显示给定索引项目的星级评分。
大多数文本属性都包含在搜索查询中, 因此即使未显示title属性, 也可以通过搜索找到文本。因此, 尚不清楚关键字属性与标题属性在本质上有何不同。
有关更多信息, 请参阅Apple的文档:developer.apple.com
最后一步是将CSSearchableItemAttributeSet与CSSearchableItem打包在一起, 并在索引中注册它。
CSSearchableItem *item1 = [[CSSearchableItem alloc] initWithUniqueIdentifier:@"https://www.notestream.com/streams/564159e4e5c24" domainIdentifier:@"notestream.com" attributeSet:attributeSet];

这里有两个新东西。 domainIdentifier属性允许你将项目分组在一起以进行批处理操作。例如, 日历应用程序中的@” meetingItem” 和@” reminderItem” 将允许你删除一种类别的所有Spotlight条目, 而保留另一种。
uniqueIdentifier属性具有更重要的作用。首先, 当用户单击CoreSpotlight索引中的项目(稍后讨论)时, 它将传递回你的应用程序。其次, 苹果公司就使用搜索基础架构的其他元素时的外观提出了一些建议。现在, 我们将使用一个字符串, 该字符串实际上是唯一表示该项目的URL。从技术上讲, 此属性可以是任何字符串, 只要它对项目是唯一的即可。
最后一步:将你创建的项目推入实际索引。
[[CSSearchableIndex defaultSearchableIndex] indexSearchableItems:@[item1, item2, item3] completionHandler: ^(NSError * __nullable error) { if (!error) NSLog(@"Search item(s) journaled for indexing."); }];

这里有几点要点:
  1. 【为开发人员揭秘iOS 9 Spotlight搜索】此方法采用一个对象数组(如果有很多数据要索引, 则可以使用其他方法对进程进行批处理)。
  2. 重要的是要认识到该方法实际上并未完成索引过程。仅当你的搜索项已排队进行索引编制时, 才会调用完成处理程序。使用CSSearchableIndexDelegate处理索引编制过程本身由于某种原因而失败并且你的应用需要处理这种情况的方案。
恭喜, 你已将项目添加到手机的CoreSpotlight搜索索引中!
为开发人员揭秘iOS 9 Spotlight搜索

文章图片
iOS 9中搜索的工作方式 当然, 苹果公司将搜索算法放在胸前, 因此值得安装示例应用程序并使用关键字。例如, 很明显, 在用户键入每个字母时, Apple通过给出截然不同的结果来最大化显示的结果:
为开发人员揭秘iOS 9 Spotlight搜索

文章图片
看起来原理是, 只需键入几个字母, 就会提出认为更合适的结果。当用户键入更多字母时, 那些早期结果将被丢弃, 而其他内容(最初估计为不太可能出现)被呈现。
更一般地说, 苹果公司只说几句关于如何提高其算法下的排名。此页面包含Apple的建议:增强搜索结果
Apple文档中的一项主要改进是, 当应用程序使用多种搜索技术对内容进行索引时, 排名将得到改善。我们将深入到另一个在下一篇文章中这些技术。同时, 当用户单击搜索结果时, 我们仍然需要实现代码来处理这种情况。
用户单击时 我们已经创建了用于用潜在的搜索结果填充索引的代码, 但是当用户单击结果时会发生什么?答案是CoreSpotlight从UIApplicationDelegate协议借用了application:continueUserActivity:restorationHandler:方法。此功能最初是在iOS 8中引入的, 用于允许用户活动在设备之间传递的切换机制(例如, 用户在iWatch上看到一个Web URL, 使用切换在iPhone Safari浏览器上进行拾取, 并最终对其进行查看他们到办公室时在Mac上使用)。
第一个挑战是确定是由于切换活动还是从Spotlight搜索调用该方法。 activity参数的activityType属性将告诉你, 但是如果代码可以在iOS 8上运行, 则需要避免这种情况下的崩溃。
以下是一些简单的代码:
- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)activity restorationHandler:(void (^)(NSArray *))restorationHandler {NSString * valueCSSearchableItemActionType; BOOL wasHandled = NO; if ([CSSearchableItemAttributeSet class]) //iOS 9 { valueCSSearchableItemActionType = CSSearchableItemActionType; } else { // iOS 8 – This method was introduced in iOS 8, so iOS 7 is not a possible scenario valueCSSearchableItemActionType = @"not supported"; }if ([activity.activityType isEqual: valueCSSearchableItemActionType]) { // Invoked via CoreSpotlight, we can assume iOS 9 from now on…NSString * activityIdentifier = [activity.userInfo valueForKey:CSSearchableItemActivityIdentifier]; wasHandled = YES; NSLog(@"Continuing user activity %@", activityIdentifier); } else {//the app was launched via Handoff protocol //or with a Universal Link }return wasHandled; }

请注意以下代码行:
NSString * activityIdentifier = [activity.userInfo valueForKey:CSSearchableItemActivityIdentifier];

这将提取在创建CSSearchableItem对象时放置到聚光灯索引中的唯一标识符。自然, 你的应用应使用此唯一标识符向用户展示他们从搜索索引中选择的内容。为了简单起见, 我们仅使用NSLog的唯一标识符。
概括 到目前为止, 我们仅研究了iOS 9搜索功能的一部分。我们已经遍历了向手机的Spotlight搜索索引加载用户可能会发现有用的东西所需的核心功能:文档, 日历项, 联系人等。当用户搜索某些内容, 看到你的应用程序的结果并单击该结果时, 该应用程序将能够处理该请求并为用户显示适当的项目。
我们尚未讨论的是与Apple正在建立的公开索引相关的技术。此索引旨在使用户即使未在手机上安装内容, 也可以在你的应用中查找内容。我们将在下一篇文章中解决。

    推荐阅读