自社で開発した ahha(ロト6・ロト7 数字予想アプリ)が、App Store の審査で 2 件のリジェクトを受けました。

コードはビルドを通っていました。実機でも落ちません。それでも審査は通りませんでした。
この 2 件は、AI にコードを書かせるときの境目がどこにあるのかを、かなりはっきり示していました。記録として残します。
先に結論を書いておきます
落ちた 2 件は、どちらも「誰もエラーを出さない場所」にありました。
- 1 件目 = 宣言はあるのに、実装がない。設定ファイルには「この機能を使う」と書いてあり、それを実行するコードがどこにもなかった
- 2 件目 = そもそもコードの外。管理画面の設問の答えが、審査側の基準と食い違っていた
コンパイラは何も言いません。テストも通ります。AI に「レビューして」と頼んでも出てきません。そこに何かが足りないという情報が、どこにも存在しないからです。
1 件目 — 宣言はあるのに、実装がない
Apple からの指摘はこうでした。
アプリは App Tracking Transparency フレームワークを使用していますが、審査時に権限リクエストを確認できませんでした(Guideline 2.1)
調べたところ、こうなっていました。
| 項目 | 状態 |
|---|---|
Info.plist の NSUserTrackingUsageDescription | ある |
| 権限リクエストのコード | ない(プロジェクト全体で参照 0 件) |
| AppTrackingTransparency の Pod | 未インストール |
| 広告 SDK・アナリティクス | 使用中(実際に広告 ID にアクセスする) |
Apple は Info.plist にこのキーがあるだけで「このアプリは ATT を使う」と判定します。ところが実際にダイアログを出すコードがないので、審査担当者の端末では何も表示されません。ここで落ちました。
このキーは、広告 SDK を入れるときに慣例で書き足されることが多いものです。リクエストのコードなしでキーだけ残っていると、それ自体がリジェクト理由になります。
なぜ、これが見つからなかったのか
ここが本題です。
この状態は、どの工程でも異常として現れません。
- ビルドは通る。
Info.plistのキーは文字列であって、対応するコードの存在を要求しない - 実機でも落ちない。ダイアログが出ないだけで、アプリは正常に動く
- 広告も表示される。同意がないので非パーソナライズ広告になるだけ
- AI にコードを見せても指摘は出ない。「書かれていないコード」は視界に入らない
最後の一点が重要です。AI は目の前にあるコードの誤りは見つけます。しかし「本来あるべきものが存在しない」ことは、それを探せと指示しない限り出てきません。設定ファイルとソースコードの整合を取れ、と誰も言わなかったのです。
この構造は、以前まとめた 8 つの失敗のうち、「問題なし」が出続けるのに確認のほうが死んでいた事例と同じです。確認する側が対象を見ていなければ、何度確認しても通り抜けます。
実装で判断が要った点
直すこと自体は難しくありません。パッケージを入れて、リクエストを呼ぶだけです。難しいのは、どこで呼ぶかでした。
相反する制約が 2 つあります。
| 制約 | 内容 |
|---|---|
| Apple の要件 | 追跡データの収集が始まる前にダイアログが出ること。このアプリでは広告 SDK の初期化がその起点 |
| iOS の挙動 | アプリが foreground active でないとリクエストが無視される。スプラッシュ表示中に呼ぶと、ダイアログが出ないまま拒否として処理される |
起動直後でもだめ、広告初期化の後でもだめ。その間に置くしかありません。
ここに UX の判断をもう一つ重ねました。このアプリは初回起動時にオンボーディング画面が出ます。その完了直後に置きました。アプリが何をするものか分からない状態で追跡の同意を求めると拒否率が上がりますし、オンボーディング画面の上にシステムダイアログが重なるのも避けられます。
実装としては、レンダリングを持たない Guard コンポーネントを 1 つ足して「リクエスト → 応答 → 広告 SDK 初期化」の順序を強制しました。ルートの useEffect はマウント時に 1 回しか走らないため、「オンボーディングが終わる時点」を捕まえられないからです。
拒否されても初期化は呼びます。広告 SDK が自動で非パーソナライズ広告に切り替えるので、広告そのものを止める必要はありません。
検証で効いたのは、新規インストール状態でのテストでした。既存インストールのまま再起動したら、背景にすでに広告バナーが出ていました。順序が守られているかは、まっさらな状態でしか確認できません。
2 件目 — そもそもコードの外にあった
もう 1 件は年齢制限(Age Rating)でした。
アプリが実際の金銭を伴うギャンブルに関する助言・ツール・予想などを含むため、「ギャンブル」を「はい」にする必要があります(Guideline 2.3.6)
ahha はロト6・ロト7 の当選番号を統計的に分析するアプリです。アプリ内で賭けるわけでも、課金してくじを買うわけでもありません。開発側の感覚では「ギャンブルアプリ」ではありませんでした。
ところが Apple の基準はこうです。
- 実際の金銭を伴う賭博に関する tips・tools・predictions を含むなら該当する
- 判定はユーザーがアプリ内でアクセスできる最も高い水準で行う
賭けの場を提供していなくても、賭けに使える予想を出していれば該当します。ここが食い違っていました。
設問は App Store Connect の年齢制限(ステップ 6)にあります。紛らわしいのは、すぐ上に「疑似ギャンブル」という別項目があることです。こちらは金銭を使わないベッティングを指すので、宝くじ予想アプリは下段の「ギャンブル」のほうに該当します。

この設問はコードのどこにも現れません。AI にリポジトリ全体を読ませても出てきません。管理画面の中にしかない情報だからです。
「はい」にすると、売れる国が減ります
ここが、同じ種類のアプリを出す方にいちばん伝えたい部分です。
設問を「はい」に変えて保存すると、警告が出ます。
年齢制限が 18+ になり、地域の法令によってアフガニスタン・アラブ首長国連邦・イラク・ガボン・サウジアラビア・ブラジル・モルディブ・モロッコ・リビア・韓国で販売できなくなります。

韓国については、公開するならゲーム物管理委員会(Game Rating and Administration Committee)のレーティング分類番号の提出が必要になります。番号を取得して入力すれば公開できますが、そのための手続きが別途発生します。
結果として、配信対象は 18+ / 173 か国になりました。

このアプリは日本国内向けなので実害はありませんでした。ただし、同じ設問に当たるアプリを多言語・多地域で出す予定があるなら、これは事前に織り込んでおくべき条件です。審査に落ちてから知ると、対応の選択肢がなくなります。「はい」にする以外の道はないからです。
境目はどこにあったのか
| 領域 | AI が扱えるか |
|---|---|
| 目の前のコードの誤り | 扱える。ここは任せてよい |
| 存在しないコード | 指示しない限り出てこない。設定と実装の整合は人が問う |
| 呼ぶ場所・順序 | 書けるが、決められない。OS の挙動と UX の判断が要る |
| 管理画面の設定 | そもそも見えない。リポジトリの外にある |
| 審査基準との突き合わせ | 見えない。基準を渡せば照合はできる |
並べてみると、AI が弱いのは「難しいこと」ではなく「情報が存在しないこと」だと分かります。難易度の問題ではありません。
だから対策も、賢いモデルに替えることではありませんでした。リポジトリの外にある条件を、こちらから中に持ち込むことです。今回でいえば、審査ガイドラインの該当箇所と、設定ファイルのキー一覧を突き合わせる工程を作ることでした。
同じところで落ちないために
- 設定ファイルのキーと、対応するコードの有無を突き合わせる。権限系のキーは慣例で足されがちで、実装が伴っているとは限らない
- 権限リクエストは新規インストール状態で確認する。既存インストールでは一度応答済みなので、出ないことに気づけない
- 年齢制限の設問は、開発側の感覚ではなく審査側の定義で答える。「ユーザーがアクセスできる最も高い水準」が基準
- ギャンブル該当は配信地域に直結する。多地域展開の予定があるなら、企画段階で確認しておく
- 審査で求められる画面録画は実機で撮る。シミュレータの録画は認められない可能性がある
記事で扱ったアプリについて
本記事の題材にした ahha は、ロト6・ロト7 の抽せん結果を統計的に分析するアプリです。過去の当せん番号から出現傾向を集計し、数字の選び方の材料として提示します。
当せんを保証するものではありません。統計は過去の記録であって、次回の抽せんとは独立しています。そのうえで、勘だけで選ぶよりは材料があったほうがいい、という方に向けたものです。
詳細はこちらです。
この記事について
2026 年 8 月時点の App Store 審査で実際に受けた指摘をもとにしています。ガイドラインも管理画面も変わります。手順ではなく、どこで判断が要ったかを残すことを目的にしました。



コメント