WWDC26:Code-along: Make your app available to Siri

App Schema によって Siri と自然言語でアプリコンテンツとのインタラクションを実現する方法のコードベース解説。前回前々回の良い復習になった。

Code-along: Make your app available to Siri


0:00 – Introduction

  • ピクニックシナリオを通じた実演:イベント検索、時間の更新、参加者へのテキスト送信、会話形式での質問応答
  • 既存アプリを Siri 対応にする流れをコードアロング形式で体験

1:43 – App Schemas and the plan

  • App Intents によるシステム連携の仕組みと App Schemas の役割を整理
    • App Schemas はコンテンツとアクションを Siri が理解できる形で記述する
    • トレーニングフレーズ不要で Siri との連携が成立する
  • サンプルアプリ CometCal で calendar ドメインを採用する 2 つの目標
    • コンテンツの理解(エンティティ)
    • アクションの実行(インテント)

3:44 – Build the CalendarEntity

  • @AppEntity(schema: .calendar.calendar) マクロでスキーマ準拠の AppEntity を作成
  • idUUID 型で指定
  • IndexedEntity に準拠して Spotlight へのインデックスを有効化
  • @Dependency でデータアクセスを注入
    • App Intent が共有リソースをインテントやクエリに注入する仕組み
    • インスタンスの再生成をせず、既に登録したオブジェクトを提供 
  • EnumerableEntityQuery を採用してすべてのカレンダー allEntities を列挙可能に
  • displayRepresentation でタイトルや画像を設定して Siri や Shortcuts での表示名を定義
  • IndexedEntity はインデックスされるコンテンツの形状を定義、コンテンツ更新に従って再インデックスが必要
    • CSSearchableIndex.indexAppEntities(_:) でエンティティを提供
    • 同様に updateAppEntities, deleteAppEntities

8:00 – Build the AttendeeEntity

  • @AppEntity(schema: .calendar.attendee) から構築
  • TransientAppEntity に準拠(IndexedEntity ではなく)
    • 参加者はイベントを通じてのみアクセスされ、一時的なエンティティであるため、識別子・クエリ・インデックスが不要
    • 同じ人が複数イベントへの参加を表明する場合、仮に参加ごとにインデックスを作成すると Spotlight で重複した結果が生じる
  • IntentPerson 型(システム標準の人物表現)と参加者のステータス・種別用の @AppEnum を導入

10:30 – Build the EventEntity

  • @AppEntity(schema: .calendar.event) から構築する中心的な IndexedEntity
  • タイトルやメモの質問に対応するセマンティックインデックスをサポート
  • CalendarEntity[AttendeeEntity] を合成して構造化
    • Siri は AppSchema 二よりこれらの構造を理解
  • Calendar.RecurrenceRule によりイベントの繰り返しルールを定義
  • 場所・アラームのユニオン値 EventLocation、イベントステータス EventEntityStatux, スパン EventSpan

14:34 – Open events with OpenIntent

  • Siri からアプリのメイン画面が開くだけでなく、対象のイベントを開いて欲しい
  • system.open スキーマに準拠した OpenEventIntent を実装
    • EventEntity を受け取り NavigationManager でイベント詳細画面へ遷移
  • Spotlight や Siri でイベントをタップすると直接詳細画面が開くようになる

15:30 – Onscreen awareness

  • 2 つのビューモディファイアでオンスクリーン認識を有効化
    • .appEntityIdentifier:イベントリストの各行に付与
    • .userActivityEntityIdentifier 付き):詳細ビューに付与
  • 「このイベント」「3 番目のイベント」のようなタイトルを言わない参照が解決できるようになる

17:18 – Create events with Siri

  • calendar.createEvent スキーマに準拠した createEventIntent を実装
    • パラメータ型を設定し @MainActor @Dependency を追加
    • perform() 内でスキーマのパラメータ(場所のユニオン値、繰り返しルール)を解決して EventEntity を返す
  • 自然言語の解釈・確認・曖昧さの解消は Siri が担当

19:24 – Update events

  • UpdateEventIntentCreateEventIntent と対称的な構造で、パラメータはオプショナル
  • IntentParametervalueState が重要なポイント
    • .set(値あり):変更を意図
    • .setnil):クリアを意図
    • .unset:リクエストに含まれていない(変更しない)

21:30 – Custom snippet views

  • インテントの戻り値型に ShowsSnippetView を追加し、カスタム SwiftUI ビューを返す
    • EventSnippetView を返すことで Siri のデフォルトカードをアプリ独自のデザインに置き換え

22:30 – Delete events

  • DeleteEventIntent は最もシンプル(イベント+繰り返し用のオプショナルなスパン)
  • 確認や曖昧さの解消は Siri が自動的に処理する

WWDC26:Build intelligent Siri experiences with App Schemas

前回の内容をコードベースでより掘り下げながら、App Schema への準拠によってアプリ固有アクションを Siri に理解させ自然言語でも実行可能にする方法れていた。App Entity、App Intent、App Schema、色々出てきてこんがらがってきた。
WWDC26:Explore advanced App Intents features for Siri and Apple Intelligence

Build intelligent Siri experiences with App Schemas


0:00 – Introduction

  • App Intents によってアプリを Siri に対応させる仕組みを解説
  • Apple Intelligence により Siri がより有能・文脈理解・パーソナルに進化

1:06 – What’s new in Siri

  • Siri が新たに得た 3 つの能力
    • アプリのエンティティへのアクセス(コンテンツの把握)
    • インテントを通じたアクションの実行
    • オンスクリーンコンテキストの理解

4:06 – Contributing content with App Entities

  • アプリのコンテンツを AppEntity としてモデル化する
  • AppEntities が表現するもの
    1. 何であるか(nouns)
      1. 識別方法
      2. 重要なプロパティ(タイトルなど)
  • これらを Siri が理解できるようにするために AppSchema に準拠する
  • スキーマは @AppEntity(schema: .messages.message) のように指定

6:21 – Entity resolution and IndexedEntity

  • エンティティを特定するにおいても、人は必ずしも正確に話すわけではない(概念や説明を話す)=完全一致ではない
  • IndexedEntity に準拠し、セマンティック検索やコンテンツ Q&A を実現する
    • @Property(indexingKey: \.textContent) でインデックス対象プロパティを指定
  • データセットが巨大など、事前インデックスが難しいデータには EntityStringQuery を使用
    • entities(matching:) で文字列に基づくリアルタイム検索を実装

9:49 – Making actions available

  • App Intents を定義すると、システムにアプリのアクションが公開される
    • Shortcuts、Spotlight、Widgets 様ざな場所に表示され、必ずしも Siri がなくともアクションを実行できるようになる
  • エンティティを App Schema に準拠させることで、そのアクションを Siri が理解できるようになり、自然言語で実行可能になる(App Schema = App Intent の特化版)
  • 複数のインテントを App Schema ドメインにグループ化することで Siri が関連アクションを把握

12:03 – Adopting a schema domain in UnicornChat

  • Messages ドメインの sendMessage スキーマを採用するエンドツーエンドの実装デモ
  • スキーマドメイン採用により Siri との会話が自然に成立する

15:39 – Moving content across apps

  • エンティティに Transferable を採用することで他アプリがそのコンテンツを操作可能になる
  • IntentValueRepresentation を使って他のアプリへの書き出し・書き込みを制御

16:00 – Working across apps: onscreen awareness

  • NSUserActivity またはビューアノテーションでビューをエンティティに紐付ける
    • NSUserActivity:単一のプライマリエンティティをビュー全体に関連付け
    • .appEntityIdentifier モディファイア:リスト内の各行など個々のビューに紐付け
  • Siri が「これ」「あれ」などの参照を解決できるようになる
  • IntentValueQuery でクロスアプリのコンテンツマッチングを実装
    • values(for:)IntentPerson などのシステム型から、既存のアプリ内エンティティへマッピング
  • IntentValueRepresentationimporting: クロージャを追加すると、一致するコンテンツが存在しない場合に新規作成も可能

21:09 – Best practices

  • スキーマセットを完全に採用することで Siri との会話が完結するように設計する
  • Xcode がビルド時に不足している関連スキーマを指摘してくれる

24:18 – Testing your integration

  • 段階的な検証アプローチ
    • AppIntentsTesting フレームワークによって、Siri 不要でプログラマティックにロジックのテストが可能
    • Shortcuts アプリでパラメタや入力の調整をしながら、アクションのユーザーへの見え方(インテントの形)を検証
    • Spotlight でエンティティのインデックスされていて発見可能かを確認
    • 最後に Siri でエンドツーエンドテスト

WWDC26:Explore advanced App Intents features for Siri and Apple Intelligence

Siri のレスポンスを App Intents によってカスタマイズする方法。Spotlight のセマンティックインデックスによって、ざっくりした指示でもアプリコンテンツに対してインタラクションできるのは良さそう。

Explore advanced App Intents features for Siri and Apple Intelligence


0:00 – Introduction

  • Siri および Apple Intelligence との連携を洗練させるための高度なテクニックを解説
  • 扱うテーマ:Siri 会話のカスタマイズ、コンテンツ検出の改善、システム連携の活用

1:59 – Customize how Siri responds

  • Siri が返すレスポンスを、App Intents によって制御、カスタマイズし洗練させる
  • 空の結果を返すことで Siri に「見つからなかった」と応答させられる
  • ProvidesDialog プロトコルで応答文をカスタマイズ
    • IntentDialog(full:supporting:) で詳細な応答文(フル文字列)と短い応答文(サポート文字列)を使い分け
    • AirPods など音声読み上げではこのフル文字列が読み上げられる
  • $label.requestValue(...) でインテント実行途中に追加情報をユーザーに要求可能(e.g. 既に実行中のアラームラベルが存在していた場合、別の命名をするか尋ねる)

4:20 – Visual responses

  • DisplayRepresentationtitlesubtitleimage を設定すると応答画面や Spotlight に反映される
  • ShowsSnippetView プロトコルで SwiftUI 製のカスタムスニペットビューを返すことが可能
    • アプリ独自のデザインで Siri の結果カードを表現できる

6:22 – Interaction donations

  • Siri がインテントを呼び出す前に追加の質問を挟むことが可能(e.g. メッセージ送信先を指定した時、コンタクトの類似した名前のうち誰が対象かを尋ねる)
  • IntentDonationManager.shared.donate(intent:result:) でユーザーの UI 操作をシステムにドネート
    • Apple Intelligence がユーザーの好みを学習し、継続中のアクティビティを追跡できるようになる
    • 過剰にドネートされるとシステムはそれらを無視することがある
  • システムインタラクション(Shortcuts 経由など)は自動的にドネートされる

9:46 – Confirmations and entity ownership

  • 副作用を持つインテントは Siri が自動的に確認を求める(e.g. 共用イベントの削除行為など)
  • OwnershipProvidingEntity プロトコルで所有権の状態を Siri に伝える
    • ownership プロパティで .unknown(自分のみ)や .shared(他のユーザーも関係)を返す、これに従って Siri がユーザーに確認を促すか判断する
    • 所有権情報を最新に保つことで Siri の確認フローが適切に動作する

11:59 – Semantic index with IndexedEntity

  • IndexedEntity に準拠し indexAppEntities で Spotlight へのインデックスを実装
    • CSSearcableIndex.indexAppEntities(_:) でセマンティックインデックスが入力
    • 意味ベースの検索でコンテンツが見つかるようになる
  • インデックスを最新に保つ仕組みと再インデックスのサポートが重要
    • ユーザーがコンテンツを追加したらインデックスを作成
    • 主要なプロパティが更新されたら再インデックス
    • コンテンツを削除したら、インデックスからもエントリを削除
  • IndexedEntityQuery を採用することで、再インデックスをサポートできる
    • ただし Core Spotlight レベルの API で再インデックスに対応していれば不要

13:32 – Structured search with IntentValueQuery

  • 大規模・サーバーサイド・頻繁に変化するコンテンツには IntentValueQuery を使用
    • e.g. アルバムはインデックスするが、含まれる曲はインデックスしない
    • values(for:) で構造化された検索入力を複数のエンティティ型にマッピング
  • AudioSearch のような入力型で検索クライテリアを受け取り、結果を返す

15:27 – In-app search

  • system.searchInApp スキーマを採用した AppIntent を実装すると、Siri 検索をアプリ UI で再実行可能
    • ドメイン採用やインデックス化の有無に関わらず利用できる汎用的なアプローチ
    • perform() 内でナビゲーション状態を書き換えてアプリの検索画面を開く

16:22 – Onscreen awareness

  • 表示中のコンテンツをエンティティに接続する 4 つのアプローチ
    • NSUserActivity :ビュー全体に単一のプライマリエンティティを関連付け
      • View Annotation API .appEntityIdentifier モディファイア:複数エンティティが存在するビュー内の特定要素に付与
    • コレクションアノテーション:リストの選択状態をエンティティ ID にマッピング
      • .appEntityIndentifier(forSelectionType:) で選択IDを返し、画面外の選択肢に対してもアノテーションすることが可能
    • カスタムキャンバスアノテーション:独自描画領域内のエンティティを登録
  • これにより Siri が「このイベント」「あの曲」などの参照を解決できる

20:51 – Leverage existing integrations

  • ユーザー通知 UNMutableNotificationContent、Now Playing、Alarm Kit の設定にエンティティを添付可能
    • content.appEntityIdentifiersEntityIdentifier の配列を設定
    • Now Playing では最も具体的なものから順に複数の EntityIdentifier を指定
    • Alarm Kit の AlarmConfigurationappEntityIdentifier パラメータとして渡す

WWDC26:Discover new capabilities in the App Intents framework

App Intents に関する2026年のアップデートについて。実装未経験で未知の領域なのだが、アプリコンテンツをシステムが既知のデータ型として与えることが可能になったことでアプリ内の連携がより密になったり、システムによるアプリコンテンツの提案をよりユーザーのコンテクストベースで行えるようになったり、さらに Siri がデバイスまたいで会話継続できるようになったりで、よりアプリのコンテンツがアプリの箱から飛び出して生活に偏在できるようになった感がある。

Discover new capabilities in the App Intents framework


0:00 – Introduction

  • App Intents フレームワークの 2026 年アップデート概要
  • Siri、Shortcuts、Spotlight、Widgets、Apple Intelligence にわたる制御・柔軟性・開発体験の向上

2:40 – Share entities across apps with ValueRepresentation

  • ValueRepresentation でアプリのエンティティをシステムが理解できる構造化型に変換して共有
    • エンティティ自体が Transferable に準拠していれば、エンティティの情報を ValueRepresentation でシステムの理解する構造体に変換して transferRepresentation として返すだけ
    • 例:ランドマークを GeoToolbox.PlaceDescriptor として書き出し、Maps でナビゲーション可能にする
  • エンティティにすでに対応プロパティがある場合はキーパスで簡潔に記述可能
    • ValueRepresentation(exporting: \.placeDescriptor)

3:45 – Register relevant entities with RelevantEntities

  • システムに自アプリのコンテンツを登録する方法
    • 1. Spotlight にインデックスする:Siriで検索取得させたい場合
    • 2. インタラクションドネーション(IntentDonationManager API):Siriとシステムにユーザーの使い方を学習させたい場合(繰り返しアクション)
      • → システムがパターンを学習し将来提案するようになる
    • 3. 未知のコンテンツの場合は? Spotlight にインデクスされていないし、インタラクションもまだドネートされていない → ReleavantEntities でシステムにヒントを与える
  • RelevantEntities API で「いつ、なぜ」のコンテキスト付きでエンティティを提案
    • 例:ワークアウト開始時に再生中プレイリストを提案
  • updateEntities(_:for:) でコンテキスト付きエンティティを登録
  • コンテキスト・エンティティ・全体の 3 段階での削除 API が用意されている

7:05 – Handle entities efficiently with EntityCollection

  • 大規模なエンティティセットを効率的に扱うための EntityCollection
  • パラメータ型を [PhotoEntity] から EntityCollection に変更するだけ
    • perform() 内では photos.identifiers を使うことでフル解決を回避
    • 1000 枚の写真のタグ付けがほぼ瞬時に完了するほどのパフォーマンス改善

8:55 – Use entities across devices with SyncableEntity

  • OS 27 から Siri デバイスを跨いで会話を継続でき、エンティティも共有可能に
    • エンティティにはIDが採番されシステムはこれを鍵に特定するが、ローカル生成されたものかもしれない(ローカルID) → デバイス共通のIDが必要(安定ID) → SyncableEntity プロトコル
  • エンティティの ID がデバイスをまたいで安定している場合はプロトコル準拠を宣言するだけ
  • ローカル ID と安定 ID が異なる場合は SyncableEntityIdentifier でペアリング
    • サーバー UUID や Cloud Kit レコード ID などが安定 ID の典型例

11:01 – Richer parameter types

  • DurationPersonNameComponents のネイティブサポートが追加
    • Siri、Shortcuts、Widgets でピッカー UI とローカライズが自動的に機能

12:38 – Union value parameters

  • @UnionValue 列挙型により 1 つのパラメータが複数の型を受け付けられるようになる
    • 例:ランドマークコレクションまたはフォトアルバムのどちらかを受け取るパラメータ
  • 各ケースの表示名を caseDisplayRepresentations で定義すると自動的にピッカーが生成される

13:26 – Extend execution with LongRunningIntent

  • LongRunningIntent で 30 秒の実行制限を超える処理が可能になる(e.g. アプリを開かずにウィジェット経由で大きな画像をアップロード)
  • performBackgroundTask ブロック内で progress を更新すると Live Activity として進捗を表示
  • CancellableIntent を組み合わせるとキャンセル処理(クリーンアップ)も実装可能
  • バックグラウンドでの GPU アクセスもサポート

15:27 – Target the right process with ExecutionTargets

  • allowedExecutionTargets でインテントの実行先プロセスを明示的に指定可能
    • .main:書き込み操作など、メインアプリが必要な場合
    • .appIntentsExtension:スタンドアロンのダウンロードなど、エクステンションで完結する場合
    • .widgetKitExtension:表示専用の読み取り操作
    • 複数指定でシステムに選択を委ねることも可能