開発者向け
iOS 27 の App Intents:Siri と App Schemas 対応ガイド
iOS 27 の App Intents と Siri 連携を解説。App Schemas、IndexedEntity とセマンティックインデックス、画面認識、iPhone Duo での IntentValueRepresentation。
AppleDuo 編集部公開 15分で読めます
このページの内容
iOS 27 の Siri は、アプリ内のコンテンツを見つけ、それに対して操作し、画面に表示されているものを理解できます。ただし、それはアプリが Siri に読み取れる形で自身を記述している場合に限られます。その記述にあたるのが App Intents です。ショートカットや Spotlight のアクションを支えるのと同じフレームワークで、iOS 27 では App Schemas、セマンティックインデックス、アプリ間でデータを共有する新しい手段が加わりました。このガイドでは、Apple が推奨する導入順に各要素を解説します。
この記事は、Apple の WWDC26 のセッションとドキュメント、Jordan Morgan の解説記事、iOS デベロッパ @sarunw の投稿に基づいています。AppleDuo チームはこのコードを製品として出荷していません。いくつかの API は iOS 27 と Xcode 27 の新機能で、そのほかは iOS 18 や iOS 26 からあるものです。リリース間で詳細が変わる可能性があります。
iOS 27 の App Intents とは?
@sarunw が述べているように、App Intent はアプリが実行できるアクションです。一度定義すれば、ショートカット、Spotlight、ウィジェットなど、システム全体で利用できます。WWDC26 のセッション「Build intelligent Siri experiences with App Schemas」で、Apple は App Intents を Siri および Apple Intelligence と連携するための基盤と呼んでいます。
基本的なインテントは、タイトルと perform() メソッドを持ちます。この形は iOS 16 から使われています。
struct OpenInboxIntent: AppIntent {
static var title: LocalizedStringResource = "Open Inbox"
static var openAppWhenRun = true
func perform() async throws -> some IntentResult {
// 受信トレイに移動する
return .result()
}
}
iOS 27 で新しくなったのは、Siri がこれらのアクションをどこまで活用できるかです。Apple の考え方では、Siri が言語の理解を担い、アプリはアクションに集中します。この役割分担を機能させるには、Siri が各アクションと各コンテンツの意味を知っている必要があります。
App Schemas とドメインで Siri がアプリを理解する仕組みは?
@sarunw は 3 つの要素でまとめています。App Intents はアクションを記述します。App Schemas はそのアクションに Siri が理解できる意味を与えます。ドメインは関連するスキーマをグループにまとめます。
Apple はスキーマを App Intents の特殊化と説明しています。スキーマも App Intents であることに変わりはなく、Siri が処理方法を理解できる形に整えられたものです。スキーマは宣言の前にマクロで適用します。AppIntent(schema:)、AppEntity(schema:)、AppEnum(schema:) のいずれかです。Apple の App schema domains のページには 3 つのグループが掲載されています。
| ドメインのグループ | 例 | 連携先 |
|---|---|---|
| 主要ドメイン | Audio、Calendar、Camera、Clock、Mail、Maps、Messages、Notes、Phone、Photos、Reminders、System とアプリ内検索 | Apple Intelligence と Siri |
| 単一目的のドメイン | Assistant、Visual intelligence | 特定の 1 つのシステム機能 |
| ショートカット専用ドメイン | Books、Browser、Files、Journaling、Presentation、Reader、Spreadsheet、Whiteboard、Word processor | ショートカットのみ(Siri は対象外) |
スキーマのドメインは iOS 18 で初めて登場しました。WWDC26 のセッションでは、Apple のメッセージングアプリのサンプルが Messages ドメインの sendMessage スキーマを採用しています。Xcode 27 はビルド時に関連するスキーマもチェックします。draftMessage なしで sendMessage を採用するとビルドエラーになり、スタブを生成する Fix-It が提示されます。
コンテンツがどのスキーマにも当てはまらない場合でも、通常の App Intents を提供できます。Jordan Morgan の iOS 27 についての解説記事では、新しい Siri の動作がスキーマを使わないアプリにどこまで及ぶのかはまだ明らかでないと指摘しています。
アプリのコンテンツを Siri で見つけられるようにするには?
アクションは話の半分にすぎません。Siri は、ユーザーが話題にしている対象も見つける必要があります。@sarunw は 4 つのステップを挙げており、それは Apple のセッションでの順序と一致しています。
| ステップ | API | 理由 |
|---|---|---|
| 1. コンテンツを記述する | AppEntity | それが何か、どう識別されるか、どのプロパティが重要かを伝える |
| 2. 意味を与える | @AppEntity(schema:) | それがどんな種類のコンテンツかを Siri に伝える |
| 3. インデックスに登録する | IndexedEntity | エンティティをシステムのセマンティックインデックスに登録する |
| 4. フォールバックする | EntityStringQuery | 事前にインデックスできないコンテンツを見つける |
ステップ 2 と 3 は 1 つの宣言にまとめられます。次は Apple の WWDC26 セッションに登場するメッセージのエンティティです。
@AppEntity(schema: .messages.message)
struct MessageEntity: IndexedEntity {
// メッセージのテキストコンテンツ
@Property(indexingKey: \.textContent)
var body: AttributedString?
}
@sarunw はこれを 3 つの判断に分解しています。コンテンツの種類、それをインデックスに含めること、そしてどのフィールドをインデックスするかです。Apple によると、IndexedEntity の採用はエンティティ解決を実現する主要な方法です。インデックスされたエンティティはセマンティックインデックスに登録され、Siri が完全一致の言葉ではなく意味で照合できるようになるからです。
indexingKey の部分は、いわば翻訳です。@sarunw の説明によると、プロパティ名は body でも、Spotlight はその値を textContent として保存します。この対応付けがなければ、どのフィールドにメッセージのテキストが入っているのかをシステムが知る手段はありません。
どの部分が新しいの?
Apple の App Intents updates のページによると、IndexedEntity は iOS 18 で、@Property(indexingKey:) は iOS 26 で登場しました。iOS 27 で加わったのは、Siri がそのインデックスを意味ベースの照合に使うことと、IndexedEntityQuery などの新しい型です。コードアロングのセッションでは、Apple はコンテンツの作成・更新後に CSSearchableIndex で indexAppEntities を、削除後に deleteAppEntities を呼び出して、インデックスを最新の状態に保っています。
コンテンツをインデックスできない場合は?
サーバー上にある、頻繁に変わる、大きすぎるなどの理由で、事前にインデックスできないコンテンツもあります。そうした場合に Apple が示しているのが EntityStringQuery です。Siri がユーザーの言葉をアプリに渡し、アプリが一致するエンティティを返します。次は Apple の例です。
struct ContactQuery: EntityStringQuery {
func entities(matching string: String) async throws -> [ContactEntity] {
let predicate = #Predicate<Person> { person in
person.name.localizedStandardContains(string)
}
let descriptor = FetchDescriptor<Person>(predicate: predicate)
let matches = try modelContext.fetch(descriptor)
return matches.map(\.entity)
}
}
文字列クエリは意味ではなくテキストで照合し、リクエストのたびにアプリのコードを実行します。可能な限り IndexedEntity を優先し、文字列クエリはそれ以外の場合に限りましょう。
Siri はアプリの画面に何が表示されているかをどう知る?
@sarunw が指摘しているように、iOS 27 の Siri は画面に表示されている内容を読み取れますが、ビューがどの App Entity を表しているかはアプリが伝える必要があります。Apple の記事「Providing contextual cues to Apple Intelligence and Siri」では 2 つの方法が説明されており、WWDC26 のセッションではそのルールが示されています。画面上に主要なものが 1 つだけある場合はユーザーアクティビティを、意味のあるアイテムが複数表示されている場合はビューのアノテーションを使います。
リストでは、各行に appEntityIdentifier(_:) を適用します。
List {
ForEach(messages) { message in
MessageRow(message: message)
.appEntityIdentifier(
EntityIdentifier(
for: MessageEntity.self,
identifier: message.id
)
)
}
}
1 つのアイテムが画面全体を占める場合は、NSUserActivity でアノテーションを付け、そのアクティビティの appEntityIdentifier プロパティを設定します。SwiftUI では、userActivity モディファイアで設定対象のアクティビティを受け取れます。Apple のコードアロングではイベント詳細ビューに EntityIdentifier 付きの .userActivity を適用していますが、コードは掲載されていないため、次は私たちによるスケッチです。
EventDetailView(event: event)
.userActivity("com.example.viewEvent") { activity in
activity.title = event.title
activity.appEntityIdentifier = EntityIdentifier(
for: EventEntity.self,
identifier: event.id
)
}
どちらの API も iOS 27 より前からあります。Apple のドキュメントでは、SwiftUI のモディファイアは iOS 18.4 から、NSUserActivity のプロパティは iOS 18.2 から利用可能とされています。また Apple は、無関係なエンティティを付けないよう注意を促しています。アノテーションはビューが表示しているデータを反映すべきです。エンティティごとにビューがないカスタム描画のコンテンツには、appEntityUIElements(_:) を使います。
Siri を通じてほかのアプリとデータを共有するには?
Transferable は、ShareLink やドラッグ&ドロップを支えるプロトコルです。iOS 27 では Siri もこれを使います。IntentValueRepresentation を返せば、1 つの準拠で双方向に対応できます。
その理由は、単なるファイルやデータには限界があるからです。Apple の例では、マップはランドマークの写真を使ってそこへの経路を調べることはできません。人、場所、名前については、iOS 27 の新機能である IntentValueRepresentation を使うと、IntentPerson、PlaceDescriptor、PersonNameComponents など、ほかのアプリが直接使えるシステムの型を渡せます。Apple のセッションでのエクスポートの例は次のとおりです。
extension ContactEntity: Transferable {
static var transferRepresentation: some TransferRepresentation {
IntentValueRepresentation(
exporting: \.person
)
}
}
受け取る値の扱い方は 2 通りあります。Apple のルールは、すでに存在するコンテンツは解決し、存在しないコンテンツはインポートするというものです。@sarunw が IntentValueQuery について説明しているように、システムが受け取った値を渡し、アプリは自分のデータの中を探して一致するものを返します。
struct ContactEntityQuery: IntentValueQuery {
func values(for input: [IntentPerson]) async throws -> [ContactEntity] {
let names = input.map(\.displayName)
let descriptor = FetchDescriptor<Contact>()
let contacts = try model.mainContext.fetch(descriptor)
let matches = contacts.filter { contact in
names.contains(where: { name in
contact.name.localizedStandardContains(name)
})
}
return matches.map(\.entity)
}
}
一致するものがない場合は、IntentValueRepresentation(exporting:importing:) でコンテンツを作成します。これは、受け取った IntentPerson から新しいエンティティを作るクロージャを受け取ります。IntentValueQuery 自体は iOS 26 からあり、Visual intelligence のために導入されました。
1 つ注意点があります。フォーラムでは、iOS 27 のベータ版でエクスポートのクロージャがまったく実行されず、代わりに Siri が確認を求めてきたというデベロッパの報告があります。このスレッドには確認された回答がないため、正式版のビルドでテストしてください。
iPhone Duo では Siri の何が変わる?
API には何の変化もありません。iPhone Duo 専用の Siri や App Intents の API は見つかりませんでした。上記のコードは、iOS 27 を搭載したどの iPhone でも同じです。
変わるのはキャンバスです。iPhone Duo を開くと、内側ディスプレイは両方向とも regular のサイズクラスを返すため、多くのアプリがサイドバー、リスト、詳細ビューを同時に表示します。このレイアウトの変化については iPhone Duo のサイズクラスのガイドで解説しています。画面に表示されるものが増えれば、Siri が「これ」や「3 番目のメッセージ」で解決すべき対象も増え、アノテーションが欠けていて Siri が推測するしかない場面も増えます。
実践的な確認ポイントをいくつか挙げます。
- すべての列にアノテーションを付ける。 分割配置でリストと詳細ビューを並べて表示する場合は、リストの行に
appEntityIdentifierを、詳細ビューにユーザーアクティビティを付けましょう。 - アノテーションを表示中のデータに結び付ける。 デバイスを折り曲げてレイアウトが変わっても、アノテーションは実際に画面に表示されているビューに追従すべきです。
- 段階的に検証する。 Apple は、ロジックには
AppIntentsTestingフレームワーク、次にインテントの形にはショートカット、インデックスには Spotlight、フロー全体には Siri を使うことを勧めています。
アプリを対応させるためのそのほかの作業には、iPhone Duo 対応チェックリストをお使いください。
まとめ
- App Intents はアクションを記述します。
@AppIntent(schema:)や@AppEntity(schema:)で適用する App Schemas は、それに Siri が理解できる意味を与えます。ドメインはスキーマをグループにまとめます。 - コンテンツを見つけられるようにする 4 つのステップ:App Entity、App Schema、セマンティックインデックスのための
IndexedEntity、フォールバックとしてのEntityStringQuery。 @Property(indexingKey:)は、bodyをtextContentに対応付けるように、アプリのフィールドを Spotlight のフィールドに対応付けます。- 画面認識には、リストの行に
appEntityIdentifierを、1 つのアイテムが画面全体を占める場合はNSUserActivityを使います。 - データの共有には
TransferableとIntentValueRepresentation(iOS 27)を、受け取った値の照合にはIntentValueQueryを採用しましょう。 - iPhone Duo でも同じ API を使います。キャンバスが大きい分、アノテーションを付けるべきコンテンツが画面に増えるだけです。
次は iPhone Duo 向けの App Store スクリーンショットを計画するか、折りたたみ向けにすでに作られたアプリやゲームをご覧ください。
よくある質問
iOS 27 でアプリを Siri に対応させるには何が必要ですか?
アクションを App Intents として、コンテンツを App Entities として定義し、Messages や Calendar などの該当するドメインの App Schemas に準拠させます。スキーマが Siri にインテントやエンティティの意味を伝えるため、トレーニング用のフレーズを書く必要はありません。
IndexedEntity は Siri にとって何をするものですか?
IndexedEntity を採用すると、アプリのエンティティがシステムのセマンティックインデックスに登録され、Siri が完全一致の言葉ではなく意味でそれらを見つけられるようになります。Apple はこれをエンティティ解決を実現する主要な方法と位置づけています。
@Property(indexingKey:) は何のためのものですか?
エンティティのプロパティの 1 つを Spotlight の属性に対応付けます。たとえば、body という名前のメッセージのプロパティを textContent キーでインデックスすれば、そのフィールドにメッセージのテキストが入っていることをシステムが理解できます。
Siri はアプリの画面に何が表示されているかをどうやって知るのですか?
アプリが伝えます。リストの各行に appEntityIdentifier モディファイアを適用して表示中の各アイテムを App Entity に対応付けるか、1 つのアイテムが画面全体を占める場合は appEntityIdentifier を設定した NSUserActivity を付けます。
Siri を通じてほかのアプリに自分のアプリのデータを使わせるには?
App Entity を Transferable に準拠させ、IntentPerson などのシステムの型をエクスポートする IntentValueRepresentation を返します。受け取った値を扱うには、IntentValueQuery で照合するか、importing を使うバリアントで新しいコンテンツを作成します。
iPhone Duo 専用の Siri API はありますか?
私たちが調べた範囲では見つかりませんでした。Siri との連携には、どの iPhone でも同じ App Intents API を使います。iPhone Duo の大きな内側ディスプレイでは一度に多くのコンテンツを表示できるため、表示中のすべてのアイテムにアノテーションを付けることがより重要になります。
出典
- Build intelligent Siri experiences with App Schemas (WWDC26) · Apple Developer
- Code-along: Make your app available to Siri (WWDC26) · Apple Developer
- Providing contextual cues to Apple Intelligence and Siri · Apple Developer Documentation
- App schema domains · Apple Developer Documentation
- App Intents updates · Apple Developer Documentation
- appEntityIdentifier(_:) · Apple Developer Documentation
- iOS 27, Your App, and Siri · Swiftjective-C (Jordan Morgan)
- An App Intent is an action your app can do · @sarunw on X
- App Intents, App Schemas and domains · @sarunw on X
- Making your app's content findable by Siri, in four steps · @sarunw on X
- Three things make a message searchable by meaning · @sarunw on X
- Three decisions, one declaration · @sarunw on X
- indexingKey is a translation · @sarunw on X
- Siri can read what's on your screen in iOS 27 · @sarunw on X
- When one item fills the screen, annotate it with NSUserActivity · @sarunw on X
- In iOS 27, Siri uses Transferable too · @sarunw on X
- IntentValueQuery: match the incoming value, or create it · @sarunw on X
- Folded, iPhone Duo is an iPhone. Unfolded, it's an iPad · @sarunw on X
- Is .appEntityIdentifier + Transferable the intended way to let Siri send an on-screen image to another app? · Apple Developer Forums
折りたたみを、アプリの一部に。
AppleDuo は iPhone Duo を本当に活かしたアプリとゲームを紹介しています。App Store へのリンクを添えて送ってください。ほかの開発者の作品も見られます。