ANTIGRAVITY LABEN
記事一覧/アプリ開発
アプリ開発/2026-07-04上級

App Intents で AppEnum が破綻する場面 — 毎日増える壁紙カタログを Siri に選ばせる EntityQuery 設計

App Intents のパラメータを AppEnum で書くと、選択肢が固定のうちは動きますが、毎日増えるコンテンツには耐えません。動的カタログを Siri とショートカットに正しく選ばせる AppEntity + EntityQuery 設計と、識別子の安定化・Spotlight 連携の落とし穴をまとめました。

antigravity413app-intents3siri3ios35swift9app-entity

プレミアム記事

Antigravity に「壁紙アプリの App Intent で、コレクションを指定して開けるようにして」と頼んだとき、返ってきた Swift は素直に動きました。AppEnum に代表的なコレクション名を並べ、パラメータの候補として提示する実装です。ショートカットアプリで試すとちゃんと候補が出る。ここで満足して push していたら、数週間後に静かに壊れていたはずです。

問題は、私が個人開発で運営している壁紙アプリのコレクションが、毎日のように増減することです。AppEnum はコンパイル時に選択肢が確定している前提の型で、実行時に増えるカタログには使えません。エージェントが書いたコードが悪かったわけではなく、「このカタログは動的だ」という前提がプロンプトに乗っていなかっただけです。ここでは AppEnum が破綻する具体的な条件と、そこから AppEntity + EntityQuery へ移す設計を、識別子の安定化まで含めてご紹介します。

AppEnum は「固定メニュー」であって「カタログ」ではありません

App Intents でパラメータの候補を提示する方法は主に2つあります。AppEnumAppEntity です。両者は似た見た目のコードになりますが、想定している世界がまったく違います。

観点AppEnumAppEntity
選択肢の決まり方コンパイル時に固定実行時にクエリで解決
向くもの並び順・テーマ・画質など有限の設定値記事・コレクション・商品など増減するデータ
件数数個〜十数個数百〜数千でも可
検索不可(全件提示のみ)文字列一致で絞り込み可
Spotlight 露出不可IndexedEntity で可能

つまり「壁紙の画質(標準・高・最高)」のような固定値は AppEnum が正解で、「ユーザーのコレクション」のように増える対象は AppEntity を使うべきです。この線引きを最初に誤ると、カタログが小さいうちは動くために、テストをすり抜けて本番で静かに劣化します。私が最初に受け取ったコードは、まさにこの取り違えでした。

判断の軸は単純です。その選択肢は次のアプリ更新を待たずに増えるか。増えるなら AppEntity です。

AppEntity は「データ」、EntityQuery は「その探し方」

AppEntity は Siri やショートカットに見せる1件分のデータを表す型です。カタログの1コレクションを、こう表現します。

import AppIntents
 
struct WallpaperCollection: AppEntity {
    // 安定した識別子。配列の添字ではなく、データ側の永続 ID を使う
    let id: String
    let name: String
    let itemCount: Int
 
    static var typeDisplayRepresentation: TypeDisplayRepresentation {
        TypeDisplayRepresentation(name: "壁紙コレクション")
    }
 
    // Siri・ショートカット上での1件の見た目
    var displayRepresentation: DisplayRepresentation {
        DisplayRepresentation(
            title: "\(name)",
            subtitle: "\(itemCount) 枚"
        )
    }
 
    static var defaultQuery = WallpaperCollectionQuery()
}

AppEntity 単体では「どうやってその1件を見つけるか」を知りません。それを担うのが EntityQuery です。ここが AppEnum との最大の違いで、実装量の大半はクエリ側に集まります。

struct WallpaperCollectionQuery: EntityQuery {
    // (1) 識別子から実体を復元する。ショートカット保存後の再解決で必ず呼ばれる
    func entities(for identifiers: [String]) async throws -> [WallpaperCollection] {
        let all = await CollectionStore.shared.load()
        let map = Dictionary(uniqueKeysWithValues: all.map { ($0.id, $0) })
        return identifiers.compactMap { map[$0] }
    }
 
    // (2) パラメータ編集画面で最初に見せる候補
    func suggestedEntities() async throws -> [WallpaperCollection] {
        let all = await CollectionStore.shared.load()
        // 全件返さず、最近使った上位だけに絞る
        return Array(all.sorted { $0.lastUsedAt > $1.lastUsedAt }.prefix(10))
    }
}

entities(for:) を軽視しないでください。これはユーザーがショートカットを保存した後、後日そのショートカットを実行するたびに呼ばれます。ここで識別子から実体を復元できないと、保存済みのショートカットが「見つかりません」で壊れます。AppEnum にはこの復元の概念がないため、動的データに使うと保存の永続性そのものが成立しないのです。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
選択肢が固定の AppEnum では動的カタログを表現できない理由を、実際に壊れる条件つきで理解し、AppEntity へ移す判断ができる
EntityQuery の entities(for:) / suggestedEntities() / entities(matching:) を役割ごとに実装し、Siri とショートカットの両方でカタログを検索・提示できる
配列インデックスを識別子に使って崩れる事故を避け、安定 ID と Spotlight 連携まで含めた運用可能な設計に落とし込める
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Antigravity Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-07-03
エージェントが書いた App Intent を Siri に喋らせる前に — 副作用で分類して確認ゲートを挟む設計
Antigravity が生成した App Intent を Siri やアシスタントに無確認で走らせると、破壊的な操作が音声一つで発火します。副作用で3分類し、確認ゲートを機械的に挟む実装と、欠落を push 前に弾く静的チェックをまとめました。
アプリ開発2026-04-20
Antigravity で iOS の App Intents を実装する: Siri・ショートカット連携を最速で構築する方法
Antigravity を使って iOS アプリに App Intents を実装する実践ガイド。Siri とショートカットアプリへの連携手順を、Antigravity が生成するコードの落とし穴と合わせて解説します。
アプリ開発2026-06-15
新 iPhone が出るたびに三項演算子を増やすのをやめる — 解像度分岐をテーブル駆動に寄せた設計
iPhone Air・17 Pro など新解像度が増えるたびに、画面サイズ判定の三項演算子を29箇所も書き足していました。端末ではなくプロファイルで考えるテーブル駆動の設計に寄せ直し、次の端末追加を1行で終わらせるまでの具体的な手順を、壁紙アプリの実装コードとともにまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →