Visual Intelligence による画像識別と、その結果のアプリへのハンドオフ実装について。
Best practices for integrating visual intelligence in your app
0:07 – Introduction
- アジェンダ:コンテンツ定義・クエリ実装・クロスプラットフォーム対応・システムストア統合
2:02 – Defining your content
- アプリコンテンツを
AppEntityとしてモデル化することで Visual Intelligence の検索結果に表示可能(AppEntity= アプリにおける名詞 e.g. アルバム) AppEntityの設計ポイントDisplayRepresentation:タイトル・サブタイトル・サムネイルを定義- 識別テキスト(
displayRepresentation)は簡潔かつ過不足なく - 画像はサムネイルサイズで提供することで読み込みが早くなる
5:03 – Implementing a query
EntityQueryの実装:識別子からAppEntityを復元するロジックIntentValueQueryでSemanticContentDescriptorのピクセルバッファから結果を返すinput: SemanticContentDescriptorからinput.pixelBufferを取得
- 画像の類似度検索:Vision フレームワークの
GenerateImageFeaturePrintRequestでオンデバイスで実現- 事前に計算済みの特徴プリントと距離閾値を使って高速に絞り込み
queryPrint.distance(to: entry.featurePrint)で距離を算出しmaxDistance以下のものを返す
- パフォーマンス考慮
- 特徴プリントは事前計算してキャッシュ(カタログ構築時に 1 度だけ実行)
- 検索時は距離計算のみで素早く応答
8:18 – Opening results
- 選択されたコンテンツに直接遷移する
OpenIntentの実装OpenIntentプロトコルに準拠しtargetパラメータにAppEntityを指定perform()は軽量に保つ(アプリがフォアグラウンドになる際に実行されるため)- Visual Intelligence 専用の
OpenIntentは作らず既存のものを再利用する
10:03 – Mac and iPad adoption
- 同じ
AppEntity・クエリ・OpenIntentを iPadOS と macOS でそのまま流用可能 - プラットフォーム差異への対応
- iOS:カメラ入力
- Mac:スクリーンショット入力、ピクセルバッファが大幅に大きくなる
- 処理前にリサイズを検討すること
12:27 – Returning multiple result types
@UnionValue型で単一クエリから複数エンティティ型を返す- アプリは
IntentValueQueryをひとつしか持てないため、代わりに各エンティティを並べてで定義できる@UnionValue enumを使用 - アルバムエンティティとコンサートエンティティの両方を同時に返す例
- ピクセルマッチだけでなく関連コンテンツも派生させると有益(e.g. アルバムアートワークで特定した同アーティストから近くのコンサートを検索)
- アプリは
12:56 – Continuing search in your app
- すぐに検索結果が見つからない場合
semanticContentSearchスキーマでアプリ内の完全検索へ誘導(「もっと見る」)@AppIntent(schema: .visualIntelligence.semanticContentSearch)を付与perform()実装でアプリの検索ビューに移動
- 入力されたコンテキストに基づき、事前に検索が絞り込まれた状態でアプリの検索ビューが開く
- フィルター・カテゴリ・より深いコンテンツへのランディングを提供できる
14:27 – System store integrations
- Visual Intelligence がシステムストアにデータを書き込み、アプリはそれを読み取る
- カレンダー:
EventKit(EKEventStore)でイベントを読み取りNotificationCenter(.EKEventStoreChanged)でストア変更を観察して自動更新
- 連絡先:
CNContactStore - 医療デバイス計測値:
HealthKit(HKHealthStore)
- カレンダー:
- 実装パターン(カレンダーの例)
- 1.
eventStore.requestFullAccessToEvents()でアクセス許可を要求 - 2.
predicateForEvents(withStart:end:calendars:)で検索範囲を指定 - 3. イベントタイトルとカタログのアーティスト名を照合して関連イベントを抽出
- 4.
EKEventStoreChangedの通知を受けて再フェッチ
- 1.
17:16 – Next steps
- 2 つの統合ポイントのまとめ
- Image Search:
IntentValueQuery+AppEntity+OpenIntent - System stores:Event Kit・Contacts・Health Kit の変更通知を観察
- Image Search:
- iOS・iPadOS・macOS 共通のコードで対応可能