2024 年に Apple が Privacy Manifest(PrivacyInfo.xcprivacy)の提出を事実上必須化してから、個人で運営している壁紙アプリ群を更新するたびに、同じファイルを書き直す細かな作業が積み重なっていきました。私自身は 2014 年から個人でアプリ開発をしており、累計 5,000 万ダウンロードを超えるストア群を一人で運用しています。リリースのたびに NSPrivacyAccessedAPITypes の項目を読み直す時間を、別の作業に回したいと感じていたところでした。
そこで先月の頭から、Privacy Manifest の生成と更新を Gemini 2.5 Pro に部分的に任せてみました。1ヶ月使ってみて見えてきたのは、「ファイル全体を生成させる」よりも「差分を読み、必要な追加項目だけを提案させる」運用のほうが現実的だ、という地味な結論です。本稿はその記録です。
なぜ Privacy Manifest 対応に Gemini を入れたか
きっかけは、AdMob 経由で SDK のバージョンを上げたタイミングで、PrivacyInfo.xcprivacy に追加すべき API 利用カテゴリが増えていたことを後から App Store Connect の警告で気付いた、という出来事です。配信が止まる種類のエラーではないのですが、配信前の整合性を一人で確認するには時間がかかります。
要件をざっくり整理すると、こうなりました。
- アプリ本体・各 SDK・サードパーティライブラリの 3 層分 の
xcprivacyを毎回突き合わせる NSPrivacyAccessedAPITypesのNSPrivacyAccessedAPITypeとNSPrivacyAccessedAPITypeReasonsをペアで読む- 新しい SDK が増えたら、Apple の Required Reasons API リストから該当理由コードを探す
- アプリ本体側で重複している宣言を取り除く
このうち「Apple の Required Reasons API リストとの突き合わせ」と「xcprivacy 同士の差分を見て重複や漏れを洗い出す作業」は、判断ロジックが定型化していて Gemini 2.5 Pro に向いていそうだと感じました。一方で「アプリの実コードのどこで該当 API を呼んでいるか」を確定する作業は、ハルシネーションを警戒する必要がある領域です。
最初の1週間で気付いた使い分け
最初の数日は、xcprivacy 全体を生成させてみたのですが、結果はいまひとつでした。返ってきた XML はそれらしく見えるのですが、NSPrivacyAccessedAPITypeReasons の理由コード(CA92.1 や 35F9.1 のような4文字コード)の組み合わせが微妙にずれることがあり、私が手で照合し直すコストが結局かかりました。
そこで、運用を次の3段階に分解しました。
xcprivacy同士を Gemini に diff させる — 既存ファイルと新しい SDK が同梱したxcprivacyを貼り付け、不足しているNSPrivacyAccessedAPITypeだけを列挙させる- Apple の Required Reasons API リストを Gemini にコピー — 新規追加が必要な API に対して、選択肢になる理由コードを提示させる(最終判断は私)
- アプリのソース該当箇所だけ私が確認 —
UserDefaultsやFileTimestampの参照箇所は手で grep して、コードに即した理由を 1 つ選ぶ
この分解で、1リリースあたりの作業時間が体感で約 40 分から 10 分前後まで縮まりました。完全自動化ではなく「ファイル横断の読み」と「リストとの突き合わせ」だけを任せる構成です。
PrivacyInfo.xcprivacy の生成を任せるときに整えたプロンプト
任せる範囲を絞ったうえで、Gemini 2.5 Pro に渡すプロンプトのテンプレートも、運用しながら少しずつ整えていきました。コツは、出力フォーマットを XML ではなく 「差分の理由付き表」 に固定することです。
あなたは Apple Privacy Manifest の差分レビュアーです。
以下の 2 つの xcprivacy ファイルを比較してください。
[ファイル A: 現行アプリの xcprivacy]
<plist>
...省略...
</plist>
[ファイル B: 新しく追加された SDK 同梱の xcprivacy]
<plist>
...省略...
</plist>
タスク:
- B に含まれているが A に不足している NSPrivacyAccessedAPIType を列挙してください
- 各項目について、A 側に追加すべき NSPrivacyAccessedAPITypeReasons の候補を、Apple 公式リストの理由コード形式で 1〜2 個示してください
- 推測ではなく「B の宣言にあった理由コード」を優先してください
- 出力形式: Markdown の表(API名 / 追加理由コード / B での宣言根拠)
このプロンプトで返ってきた表を、私が xcprivacy に手で反映していくのが現在の運用です。XML を直接書き換えさせると Property List のクォート位置が崩れたりするので、最終生成は Xcode の Property List Editor 任せにしています。
ちなみにこの「出力をフォーマットで縛る」コツは、Gemini に限らず Claude や ChatGPT でも同じだと感じます。生成タスクをいちど「読み取りタスク」に翻訳してから渡すと、ハルシネーションがぐっと減ります。
試して合わなかった3つのこと
期待していたほどうまくいかなかった使い方も書いておきます。
1つ目は、Privacy Manifest を Swift コードから自動生成させる試みです。 「UserDefaults を参照しているコードを grep して、対応する NSPrivacyAccessedAPIType を xcprivacy に書き出してください」と頼んでみたのですが、サードパーティライブラリ内部の UserDefaults 参照まで列挙されてしまい、ノイズが多すぎました。アプリ本体のターゲットだけに絞れば多少マシになりますが、最終的に手で確認する手間が変わらず、運用に組み込むのはやめました。
2つ目は、複数アプリの xcprivacy を一括チェックさせる運用です。 5本ぶんの XML をまとめて貼ると、1ファイルあたりの粒度が落ち、差分の出し漏れが増えました。1ファイルずつ独立に処理させたほうが品質が安定します。これは Gemini 2.5 Pro のロングコンテキストを過信した失敗でした。長く読めることと、長く読んだうえで正確に差分を取れることは別の能力なのだと、改めて気付かされました。
3つ目は、App Privacy Details(App Store Connect のプライバシー回答)との同期です。 Privacy Manifest と App Privacy Details は内容が連動するべきですが、後者は質問項目の意図を Apple のドキュメントとあわせて読まないと回答できないため、Gemini に要約させるよりも、Apple の英語ドキュメントを自分で精読した方が結局速かったです。ここは AI で短縮できないと割り切りました。
1ヶ月運用して見えてきた所感
正直なところ、Privacy Manifest 作業の総時間は半減程度で、想定していた「9 割削減」には届きませんでした。それでも、月に十数本のリリースを一人で回している身からすると、地味に効きます。私自身、両親方の祖父がともに宮大工で、子どもの頃から「丁寧に組み上げる」という感覚を当たり前に見てきました。AI を入れる場所も、勢いに任せて全自動にするよりは、判断の濃い部分だけ人が残るくらいの組み方が、自分には合っているのだと改めて感じます。
短くまとめると、現時点での私の使い分けはこうなっています。
- Gemini 2.5 Pro に任せる: 既存
xcprivacyと SDK 同梱xcprivacyの差分抽出、Required Reasons API リストとの突き合わせ - 自分で判断する: 実コードに対する
NSPrivacyAccessedAPITypeの最終確定、App Privacy Details の回答 - 任せない: アプリ本体ソースからの全自動生成、複数アプリの一括処理
来月は、Claude in Chrome 経由で App Store Connect の警告画面を読み取り、Gemini 側の差分提案にフィードバックする小さなパイプラインを試したいと考えています。同じように個人で iOS アプリを運用されている方の参考になれば嬉しいです。お読みいただきありがとうございました。