iOS 9の「Search API Best Practices and FAQs」が公開されたので読み解いてみた

iOS 9の「[Search API Best Practices and FAQs](https://developer.apple.com/library/prerelease/ios/technotes/TN2416/_index.html#//apple_ref/doc/uid/DTS40016269)」が公開された(2015/06/29更新)ので読み解いてみましたʕ ·ᴥ·ʔ

Search APIは、ざっくり言うと、iOSアプリ側やWebでちょっとした実装を挟み込むと、それがSpotlight経由などで検索可能(ローカルだけでなく他のユーザーにも伝播するなど)となるものです。

- WWDCのセッションとしては [Introducing Search APIs - WWDC 2015 - Videos - Apple Developer](https://developer.apple.com/videos/wwdc/2015/?id=709) に相当
- 日本語の分かりやすい記事: [WWDC2015で発表されたiOS9 Search APIsまとめ - NSBlogger](http://nsblogger.hatenablog.com/entry/2015/06/18/ios9_core_spotlight)
- 実装観点だとこれも良い記事: [How to add Core Spotlight to index your app content – a free Hacking with Swift tutorial](http://www.hackingwithswift.com/read/32/4/how-to-add-core-spotlight-to-index-your-app-content)


僕自身、上記資料を読んでも不明な点がちらほらあって、まさにかゆいところに手が届くようなドキュメントです(　´･‿･｀)

というわけで読み解いていきます（｀・ω・´）

# PublicとPrivate

検索対象コンテンツはPublicとPrivateに分かれます。

## Private

- `NSUserActivity`および`CoreSpotlight `APIによってインデックスする
- ユーザーの作ったコンテンツや主要画面などを検索対象に出来る
- その端末内に閉じて検索可能

## Public

- Applebotというクローラーで、特定のマークアップが施されたWebサイトの情報が拾われる
- `NSUserActivity`で`public`指定されたものも対象となる
- SpotlightのSearchやSafariの候補一覧などに現れる
	- 複数のユーザー経由で拾われたりすると一覧に現れやすくなる
	- 情報収集は匿名で行われる

このあたりは、WWDCの動画や資料を見れば分かるところですね。

# ベストプラクティス

## 検索結果をリッチにするとランキング上がりやすい

イメージ・レビュー・レーティング・アクションなど最適なものを積極的に載せましょう

WWDC資料から拝借するとこのあたりヽ(・ω・｀）

![Screen Shot 2015-07-01 at 15.06.13.png](https://qiita-image-store.s3.amazonaws.com/0/19398/1cc306f0-5532-40b6-16e2-c11a7f34b1fc.png "Screen Shot 2015-07-01 at 15.06.13.png")


![Screen Shot 2015-07-01 at 15.06.31.png](https://qiita-image-store.s3.amazonaws.com/0/19398/17641a4e-6b25-1513-01be-db3e093bbfc2.png "Screen Shot 2015-07-01 at 15.06.31.png")

## 検索結果からアプリへの遷移はまっすぐスムーズに

クルクル挟んだり余計な画面遷移は極力避けてすぐにコンテンツを出しましょう。

WWDCの資料では伝わらない(´・︵・｀)
WWDC動画の終盤見てくださいヽ(・ω・｀）

![Screen Shot 2015-07-01 at 15.10.01.png](https://qiita-image-store.s3.amazonaws.com/0/19398/fc76e6c6-124c-6167-9701-666d65256447.png "Screen Shot 2015-07-01 at 15.10.01.png")


## スピードは大事

検索結果タップからコンテンツが表示されるまでの時間は計測され、ランキングに影響を及ぼす。

`func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: ([AnyObject]?) -> Void) -> Bool`の`restorationHandler`が呼ばれるまでの時間がAppleに裏で送られるとエスパーʕ ·ᴥ·ʔ

## 常にユーザーが作ったコンテンツをインデックス対象としましょう

> Always index user-generated content.

と書いてあるけど、訳合ってるかな？

## 同じアイテムを複数種類のAPIでインデックス対象とする場合、同じIDを振りましょう

Search APIは以下の3つから構成されます。

- NSUserActivity API
- CoreSpotlight API
- Web Markup API

以下をしないように気をつけましょう

- 同じアイテムに違うIDを振る
- 違うアイテムに同じIDを振る

適切にIDを振ればAppleが同じコンテンツとしてよしなに管理してくれてランクも上がりやすくなります。

3つのAPIを同じアイテムに使う場合、URLをIDとして使うのが推奨らしいですʕ ·ᴥ·ʔ

# 3つのAPIをそれぞれ簡単に説明

それぞれ5つずつ箇条書きで説明されていましたが、書くの大変なのと、WWDCの内容の要約なので、とりあえずスキップします。
気が向いたら追記するかもです。(PRいただけると嬉しいかも)

# Search API FAQ

「ベストプラクティス」もWWDCの要約みたいなものだったので、ここからがドキュメントの肝です（｀・ω・´）

## Search APIを使うメリット

- 各種Search APIを組み合わせて使うと、SpotlightやSafari検索に出るので、アプリおよびそのユーザーが興味を持っているコンテンツののエンゲージメントや見つけてもらいやすさ向上に繋がる
- アプリがインストールされていないユーザーに対しても、検索結果に現れることもあり、インストールへの動線ともなる
- すでにHandoffを組み込んでいる場合は、ごくわずかな作業で、ユーザーがアプリの使用履歴・機能・主要な画面の検索が出来るように対応出来る。

## Search APIの使い分け

### NSUserActivity

- どうアプリを使ったかなどによって変わっていくアプリの状態トラッキングに使える
- ユーザーがそのアプリで過去に利用した機能・画面などをSpotlight経由などで簡単に呼び出せるような目的に使う
- 必要に応じてpublicにも出来るが、情報は匿名で収集されてプライベートな情報はシェアされない

### CoreSpotlight

- アプリのコンテンツを検索対象とする
- privateのみで、publicには出来ない
- Search extensionを使用すると、バックグラウンド・終了状態でもインデックス可能
	- インデックス情報を新しく保てる

### Web Markup

- アプリコンテンツと同じものがWeb上にも存在する場合に指定すると良い
- Applebotがクロールして検索結果に出してくれる
- Web Markupを良い感じに施すと、検索結果がリッチになって高いエンゲージメントやアプリへのスムーズな動線に繋げられる

## どんなコンテンツをインデックスすれば良い？

- ユーザーに閲覧・作成・収集されたどんなコンテンツでもインデックス対象になり得る
- アプリの重要な画面・機能も対象
- デバイスにダウンロードされたメッセージ・コンテンツ・アイテム
	- 起動状態じゃなくても可(上述の`Search extension`のことだと思う)

## 公開しているWebサイトは無いけどアプリ内に公開コンテンツがある場合は、どのようにするのが良い？

- publicなNSUserActivityと、CoreSpotlightを使いましょう
- ただしコンテンツ全てをインデックス対象とするべきではなく、人気度などが高いものなどに絞りましょう
- 数千個のアイテムをインデックス対象とするべきではなく、ユーザーが実際に見たり、他の人にとっても価値があるであろうものに絞りましょう

## Search API使ってるのに検索結果に現れなくてつらいのですが、どうすれば良い？（´；ω；｀）

- 正しく実装していれば、検索結果に即座に反映される
- 違うキーワードを試してみてください
- ただし、publicなNSUserActivityは、ある程度の数が貯まった後に現れる
- Web Markupも同じく、Appplebotにクロールされて一定条件を満たした後に現れる

## ランキングアップの仕方教えて(　´･‿･｀)

- とにかくリッチな検索結果にしましょう
	- サムネイル・タイトル・注釈
	- 可能なら、レーティング・アクション(電話など・音楽や動画の再生)
- 検索結果に現れた後のタップ率(エンゲージメント)重要
	- せっかく現れたのに見逃されると逆効果なので、キーワードは適切なものに絞りましょう
	- 省略系など実際にそのキーワードを調べたいユーザーを救う冗長性は有効
- タップされたら素早くスムーズにコンテンツに誘導しましょう
	- この速さもスコアに計上される

## アプリをインストールしていない端末の検索結果にも表示させるには？

- そのコンテンツの公開サイトがあるならWeb Markupを使いましょう
	- Applebotがクロール出来る必要があるので、ログインしないと見られないコンテンツは不可
- あるいはpublicなNSUserActivitiesでも良い

## Webサイトからのディープリンクは何が良い？

- `Universal Links`と[Smart App Banners](https://developer.apple.com/library/mac/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html)がベスト
- Twitter CardsやFacebook App Linksも良いです


`Universal Link`についてはこちら: 
[Seamless Linking to Your App - WWDC 2015 - Videos - Apple Developer](https://developer.apple.com/videos/wwdc/2015/?id=509)


## どんなスキーマがWeb Markupとしてサポートされてる？

> Open Graph audio and video. Also, AggregateRating, Offers, PriceRange. InteractionCount, Organization, Recipe, SearchAction and ImageObject from Schema.org.



## 検索結果への電話や再生アクションの載せ方は？

- [Organization scheme](http://schema.org/Organization)の
	- [Postal Address schema](http://schema.org/PostalAddress)
	- [Audio Object schema](http://schema.org/AudioObject)
	- [Video Object Schema](http://schema.org/VideoObject)
- [Open Grash Protocol](http://ogp.me)のAudio or Video schemas

## ユーザーのプライバシーは守られる？

- NSUserActivityのデフォルトはprivate
	- public指定でも、hash化されて収集される
- CoreSpotlightは完全private
	
![Screen Shot 2015-07-01 at 16.19.29.png](https://qiita-image-store.s3.amazonaws.com/0/19398/959d2483-4dcd-96b0-5947-a16bf030b5b8.png "Screen Shot 2015-07-01 at 16.19.29.png")

## Search APIサポート端末は？

- iOS 9インストール可能な端末全て
	- iPhoneは4s以降
	- iPadは2以降

## OSXでもSearch API使える？

- CoreSpotlight: ×
- NSUserActivity: ×

ただし、Web検索結果はOSX上にも現れる。


# 最後に

この資料のおかげでSearch APIとどう付き合っていくかイメージがより湧いた気がします。
あとは、実装のための詳細なリファレンスを待ってます。

![mate.png](https://qiita-image-store.s3.amazonaws.com/0/19398/282da00b-a418-46af-5013-b8e80eec554d.png "mate.png")
自作スタンプ([ラヴさん (ラブラドール) - LINE クリエイターズスタンプ](https://store.line.me/stickershop/product/1000854/ja))より拝借