iOS程序员

关于 iOS Search API 的相关研究

移动端

NSUserActivity 相关

与搜索相关的方法/属性(苹果在 iOS 8 中就已经加入 Handoff 功能,这次更新主要是 NSUserActivity 在搜索中的功能):

  • eligibleForHandoff:布尔值
  • eligibleForSearch: 布尔值,为 YES 时会加入本地索引
  • eligibleForPublicIndexing:布尔值,为 YES 时会传到云端索引
  • title: 标题 字符类型
  • keywords: 关键字,NSSet 类型
  • contentAttributeSet:关联的 CSSearchableItemAttributeSet
  • userInfo: 相关的信息,字典类型
  • webpageURL:网页 URL

从 Handoff 到应用的回调:

- (BOOL)application:(UIApplication *)application
  continueUserActivity:(NSUserActivity *)userActivity
  restorationHandler: {
    NSString *activityType = userActivity.activityType;
    if ([activityType isEqual:@"com.mycompany.activity-type"]) {
        // Handle restoration for values provided in userInfo
        return YES;
    }
    return NO;
}

参考文档:

  1. Use NSUserActivity APIs to Make App Activities and States Searchable
  2. Handoff Programming Guide
  3. NSUserActivity Class Reference

CoreSpotlight 相关

目前苹果还没有放出文档,只能看 iOS 9.0 的更新文档和每个类暴露的接口 相应的类:

  • CSSearchableItemAttributeSet
    • initWithItemContentType::kUTTypeImage 等类型
    • title:标题
    • contentDescription:说明
    • contentURL: 相关的 URL
    • thumbnailData / thumbnailURL:缩略图
    • keywords:关键字
    • ...
  • CSSearchableItem
    • initWithUniqueIdentifier:domainIdentifier:attributeSet::初始化,Unique Identifier 为唯一标示,domainIdentifier 为Searchabble Item 的分组
    • expirationDate:设置过期日期
  • CSSearchableIndex
    • - (void)indexSearchableItems:completionHandler::添加/更新索引
    • - (void)deleteSearchableItemsWithIdentifiers:completionHandler::删除指定 identifier 的索引
    • - (void)deleteSearchableItemsWithDomainIdentifiers:completionHandler::删除指定 domain 的索引
    • - (void)deleteAllSearchableItemsWithCompletionHandler::删除所有索引
    • - (void)beginIndexBatch:开始批量操作
    • - (void)endIndexBatchWithClientState:completionHandler::结束批量操作
    • - (void)fetchLastClientStateWithCompletionHandler::异步获取应用最后一次存储的客户端状态信息
  • CSSearchableIndexDelegate
    • - (void)searchableIndex:reindexAllSearchableItemsWithAcknowledgementHandler:
    • - (void)searchableIndex:reindexSearchableItemsWithIdentifiers:acknowledgementHandler:

从搜索到应用的回调:

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

    if ([[userActivity activityType] isEqualToString:CSSearchableItemActionType]) {
        // This activity represents an item indexed using Core Spotlight, so restore the context related to the unique identifier.
    // The unique identifier of the Core Spotlight item is set in the activity’s userInfo for the key CSSearchableItemActivityIdentifier.
        NSString *uniqueIdentifier = [activity.userInfo objectForKey:CSSearchableItemActivityIdentifier];
    }
}

参考文档:

Use Core Spotlight APIs to Make App Content Searchable


Web 端

开启应用搜索

  1. 允许苹果发现并索引你的网站(应用添加 Support URL 和 Marketing URL)
  2. 确保你的网站包含移动深度链接(Mobile Deep Links)的标记(Smart App Banner)
  3. 使你的应用能够处理深度链接,即可以处理通用链接(Universal Link),通用链接有以下好处:
    • 唯一
    • 安全
    • 可伸缩
    • 应用和网站之间的无缝结合
  4. 为结构化数据添加标记(可选,但是强烈建议)

深度链接注意事项

  • 深度链接需要通过网站暴露
  • 用 Smart App Banner 或者相应的替代标准

深度链接的方案

由于提供以上支持都比较简单,所以就不在多做说明了,具体的可以点击以上链接进行查看

在应用中支持深度链接

深度链接会调用应用的 - (BOOL)application:openURL:sourceApplication:annotation: 方法,只需要在这里做一些逻辑处理就行了

丰富搜索结果

主要是通过语义标记来使苹果知道该如何显示,搜索结果不只是可以包括标题和描述,还可以包括图片,结构化数据和动作。丰富搜索结果可以让用户更爽,还可以提高你的排名。

丰富搜索结果支持一下几种格式:

  1. Open Graph

    <meta property="og:image" content="http://example.com/hello.jpg">
    <meta property="og:audio" content="http://example.com/music.m4a">
    <meta property="og:video" content="http://example.com/cats.mp4">
    
  1. schema.org Microdata:

     <div itemprop="aggregateRating" itemscope itemtype="http://schema.org/AggregateRating">
         <span itemprop="ratingValue">4</span> stars -
         <span itemprop="reviewCount">250</span> reviews
     </div>
    
  2. schema.org JSON-LD:

     <script type="application/ld+json">
     {
         "@context": "http://schema.org",
         "@type": "AggregateRating",
         "ratingValue": "4",
         "reviewCount": "250"
     }
     </script>
    

schema.org Microdata 目前只支持以下类型:

  • AggregateRating
  • Offers
  • PriceRange
  • InteractionCount
  • Organization Recipe
  • SearchAction
  • ImageObject

要支持起来还是比较简单的,以 CCTalk 为例举两个例子(目前还不支持 Event 类型,但是 CCTalk 和 Event 类型是最接近的一个),以下为网页标记语言的 Microdata 示例(日期格式必须为 ISO 8601 日期格式):

<div class="event-wrapper" itemscope itemtype="http://schema.org/Event">
  <div class="event-title" itemprop="name">【一起早自习】早读直播间39</div>
  <div class="event-title" itemprop="description">【一起早自习】早读直播间39 描述</div>
  <div class="event-date" itemprop="startDate" content="2015-07-03T10:00Z+08:00">2015年07月03日 10:00—11:00</div>
  <meta itemprop="endDate" content="2015-07-03T11:00Z+08:00" />
  <meta itemprop="eventStatus" content="http://schema.org/EventScheduled">
  <div class="event-venue" itemprop="location" itemscope itemtype="http://schema.org/Place">
    <span itemprop="name" content="47">英语大厅</span>
  </div>
  <div itemprop="performer">
          <span itemprop="name">快酷公开课助教Luna (125门课)</span>
  </div>
</div>

JSON-LD 实例:

<script type="application/ld+json">
{
  "@context": "http://schema.org",
  "@type": "Event",
  "name": "【一起早自习】早读直播间39",
  "location": {
    "@type": "Place",
    "name": "47"
  },
  "eventStatus": "http://schema.org/EventScheduled",
  "startDate": "2015-07-03T10:00Z+08:00",
  "endDate": "2015-07-03T11:00Z+08:00",
  "performer": {
      "name": "快酷公开课助教Luna (125门课)",
  }
}
</script>

参考文档:

  1. Use Web Markup to Make App Content Searchable
  2. http://schema.org/docs/schemas.html
  3. http://schema.org/Event
  4. http://dev.twitter.com/cards/mobile
  5. http://applinks.org
  6. http://ogp.me

通用链接(Universal Link)

如果网站和应用实现了此功能,当在 iOS 端打开匹配的链接是会直接打开应用,否则会在 Safari 中打开链接。最好在网页中加入 Smart App Banner,一方面可以跳转到应用的下载页有利于推广,另一方面有利于搜索引擎搜索和关联

注意事项

  • 开启 Associated Domains,添加以 applinks: 开头的域名(比如 applinks:www.cctalk.com)
  • 网站根目录添加 apple-app-site-association 文件并签名(通过网站证书签名,网站证书必须经过 Safari 认证的)
  • 通过 application:continueUserActivity:restorationHandler: 方法回调应用

Xcode 中的设置:

Enable Associated Domains

apple-app-site-association 文件示例:

{
  "applinks": {
        "apps": [],
        "details": {
            "J52Z9F8XVP.com.example.app": {
                "paths": [
                    "/course/*",
                ]
            }
        }
    }
}

apple-app-site-association 签名(MIME 类型必须为application/pkcs7-mime):

cat json.txt | openssl smime -sign -inkey example.com.key
                            -signer example.com.cert
                            -certfile intermediate.cert
                            -noattr -nodetach
                            -outform DER > apple-app-site-association

参考文档:

  1. Promoting Apps with Smart App Banners
  2. Use Universal Links to Enable Your App to Handle Links to Your Website
  3. Web Browser–to–Native App Handoff
  4. Breaking down iOS 9 Universal Links

相关 WWDC 视频