本稿は Apple Developer Program にログインせずに得られる情報で構成されています。また執筆時点での iOS 9 のバージョンはβ2であり、リリース版とは状況が異なる点があることをご了承ください。

こんにちは。AmebaアプリのiOS版を開発しているなめき @Ridwy です。

運良くチケットが当たってWWDC 2015に参加してきました。 iOS 9, OS X El Capitan, watchOS 2の3つの新OSとともに今年も様々な内容が発表されましたね。

特に iOS 9 でユーザ体験を大きく変えそうな要素としては、検索の強化とアプリへのシームレスな連携 (Deep Link) があります。これまで検索といえば「ググってWebページを閲覧する」という感じでしたが、iOS 9 からは対応アプリがインストールされていれば結果を直接アプリで見られるようになります。また、サードパーティ製アプリ内のデータも検索可能になり、アプ リへのアクセスがグッと楽になりそうです。


AndroidのApp Indexing機能と言い、検索とアプリの連携については近年熱くなってきているように思います。今回はiOS 9 のパブリックβ公開を目前に控え、強化された検索機能について調べてみました。


どうやって使うの?

検索は Spotlight か Safari の検索窓から行います。もちろん、Siriに話しかけても良いです。 Safari の結果には、コンテンツが Web上にもあるものが表示されるようです。

以下は Session 709 で紹介されていた Spotlight での検索結果の例です。表示内容はサムネイル、タイトル、説明、住所...となかなかリッチです。ここから電話をかけたり、(この例には表示されていませんが)動画や音楽を再生したり、経路案内を開始したりといったことも可能です。

結果をタップするとアプリに遷移し、アプリで内容を確認できます。他の結果が見たければステータスバーの「Back to Search」をタップして検索結果画面に戻れます。遷移アニメーションはナビゲーションの動きに似たさりげないものになっており、連携がスムーズに感じ られます。また、このアニメーションのためかホーム画面の一番左にSpotlightのスペースが復活しています。

何を調べられるの?

少し分かりにくい表現になりますが、Cloud IndexDevice Index に登録されているものが検索結果に現れます。Cloud Index はすべてのデバイスから参照されるクラウド上のインデックス、Device Index は端末固有のインデックスです。これらのインデックスには WWDC 2015 で発表された Search API によってサードパーティもアイテムを追加できます。

Cloud Indexには、レシピアプリならレシピ、ホテル検索アプリならホテルの情報などが登録されていると便利そうです。Device Indexには、ユーザが作成したデータやプライベートな情報を入れると良さそうです。

特筆すべきなのは、特定アプリをインストールしていなくてもインデックスにあるものは検索結果に現れる点です。タイミング的にアプリがユーザの目に触れる良いチャンスになりそうですね。

インデックスへの登録方法

Search API には CoreSpotlight API, NSUserActivity, Web Markup の3つがあり、それぞれ登録できる内容やインデックスが異なっています。


CoreSpotlight API と NSUserActivity はiPhone 4s, iPad 2, iPad (3rd generation), iPad mini, そして iPod touch (5th generation)ではサポートされません。 Web MarkupによるものはiOS 9がインストールできる全てのiOS端末に加えてOS Xでも検索できます。

Core Spotlight APIs

Core Spotlight APIs を使うと、Device Index への登録・更新・削除が可能です。 CSSearchableItem が検索可能なアイテム、CSSearchableIndex がインデックスを表すクラスで、こんな感じに登録できます。

let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUTTypeImage as String)
attributeSet.title = "Title"
attributeSet.contentDescription = "Description"
attributeSet.thumbnailData = UIImagePNGRepresentation(UIImage(named: "photo")!)
let item = CSSearchableItem(uniqueIdentifier: "123",                domainIdentifier: nil, attributeSet: attributeSet) CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([item]) { _ in }

iOS 9.0 API Diffs を見ると CSSearchableItemAttributeSet には曲、写真、動画のメタデータや電話番号や位置情報などの多くのプロパティがあります。これらを使ってリッチな結果を表示したり、詳細な条件での絞り込みが可能になるのだろうと思われます。

Core Spotlight APIsはバックグラウンドでもインデックスを操作できるので、Push通知と組み合わせると最新の情報を検索できるようにすることが可能です。

NSUserActivity

NSUserActivity はアプリの状態を保存しておくことができるクラスで、iOS 8で登場したデバイス間で作業を引き継げるHandoff機能のために導入されたものです。 iOS 9 では NSUserActivity を検索のインデックスに追加できるようになりました。

検索機能に関係するNSUserActivityの主なプロパティ

// Enable Capabilities 
var eligibleForSearch: Bool
var eligibleForPublicIndexing: Bool

// Provide Attributes and Keywords
var title: String?
var keywords: Set<String>
var contentAttributeSet: CSSearchableItemAttributeSet?
var expirationDate: NSDate
// Restoring on the Web
var webpageURL: NSURL? // Safariからの検索やアプリ未インストール時に表示したい場合必要

eligibleForSearch = true とすると Device Index に、eligibleForPublicIndexing = ture とすると Cloud Index に登録できます。 (ただしプライベートな情報がCloud Indexで展開されてしまうのを防ぐため、一定数以上同じものが追加された時に検索可能になるという事です。)

有効期限を設定できるのが特徴的で、最近ユーザーが行った作業の履歴を表示するのに向いています。 自前のWebコンテンツを持っていないアプリの場合、これが Cloud Index に登録するための唯一の方法になります。

Web Markup

Webページに特定のアプリへの Deep Link の情報を記載すると、ページのコンテンツをアプリで見る事が可能になります。Applebot という Apple のクローラーが、アプリへの Deep Link を Web から収集して Cloud Index に登録してくれます。アプリのサポートURLとマーケティングURLから探しだすということなので、この2つが重要になってきますね。

サポートされる Deep Link のフォーマットは Smart App BannersTwitter Cards, Facebook の App Links です。

Smart App Banners

<meta name="myAppName" content="app-id=myAppID, app-argument=myURL">

Twitter Cards

<meta name="twitter:app:name:iphone" content="myAppName">
<meta name="twitter:app:id:iphone" content="myAppID">
<meta name="twitter:app:url:iphone" content="myURL">

Facebook's App Links

<meta property="al:ios:app_name" content="myAppName">
<meta property="al:ios:app_store_id" content="myAppID">
<meta property="al:ios:url" content="myURL">

myAppName はアプリ名、myAppID は App Store でのID、myURLは遷移時にアプリに渡されるURLで、アプリ側はこのURLからどんな情報を表示すれば良いのかを判断します。

これだけしか記載がない場合、検索結果にはページのtitleタグとdescriptionタグの内容しか現れません。結果をよりリッチにするには Open Graph または schema.org で定義されているフォーマットで情報を追加します。

WWDC15 Session 709 Introducing Search APIs より


Open Graph の audio, videog と Schema.org のスキームの AggregateRating, Offers , PriceRange, InteractionCount, Organization, Recipe, SearchAction, ImageObject がサポートされています。

まとめ

この機能がユーザーにとって便利なものになるかどうかはIndexの質に左右されるところが大きいですが、うまくいけば情報へのアクセスが格段にスムーズになるはずです。

参考