iOSアプリの審査は、通るまでやり取りが続く。現在進行中なので結末はまだない。ただ、2回のリジェクトで受けた指摘の内容が「なるほど」なものと「そういうことか」なものに分かれていて、忘れないうちに記録しておきたかった。
個人開発でチャットアプリを作っている人に、何か届けばいい。
Reject ① — May 22, 2026
「匿名」という単語が、弾かれた。
初回のリジェクトは2件同時だった。一つ目は想定外だった。
// Apple Review — Guideline 1.1
The app's marketing includes terms or images that reference objectionable content or services. These references can be found in the app's metadata, including, but not limited to, the following metadata field(s): keywords — 匿名
キーワード欄に入れていた「匿名」という単語が引っかかった。コードの問題ではなく、App Store Connectのメタデータの問題だった。
「匿名」という言葉は、Appleの自動審査において不適切なコンテンツや危険行為と結びつけて判定されやすい。アプリの実態がどうであれ、キーワードに含まれているだけで対象になる。
対応はシンプルだった。「匿名」を削除して、「ニックネーム制で個人情報を共有しない」という説明表現に切り替えた。ビルドの変更は不要で、メタデータの修正だけで済んだ。
// 学び
Appleの審査はコードだけでなく、キーワード・説明文などメタデータも審査対象になる。「匿名」「ランダム」「無制限」といった言葉は、機能に問題がなくても弾かれる可能性がある。申請前にApp Store Connectの文言を一度見直す価値がある。Reject ① — 同時指摘
テストモードが、起動しなかった。
もう一つの指摘は、テスト用の隠しトリガーが再現できなかったというものだった。
// Apple Review — Guideline 2.1(a)
We followed your instruction, but the test mode could not be triggered.
チャットアプリの審査では、レビュワーがテストできる状態を用意する必要がある。そのためにテスト専用のトリガーを実装していたが、手順が複雑すぎた。画面を複数回タップした後に別の操作を組み合わせる2段階ジェスチャで、レビュワーが再現できなかった。
「指示通りやったが起動しなかった」はバグ扱いになる。隠しジェスチャは、自分にとっては自明な操作でも、初見の人間には伝わらないことがある。
対応として、トリガーを単一の動作に簡略化した。4回タップするだけ。操作している間は進行中であることを画面に表示し、「効いていないから連打する」という状況も防いだ。
// 学び
テストトリガーは「単一・短時間・誤操作の余地がない」設計でないと、レビュワーには届かない。複数ステップの隠しジェスチャは確実性を下げる。進行中のフィードバックを画面に出すことも、「壊れていない」ことの証明になる。Reject ② — May 31, 2026
テストモードが、審査になっていた。
2回目のリジェクトが、一番考えさせられた。
// Apple Review — Guideline 1.2
The app connects users for one-to-one random and anonymous text chats. Since random and anonymous chat is not appropriate for the App Store, the app must be revised to:
1. Display identifiable information about the user you are about to connect with before the chat begins
2. Allow the user to accept, decline, or skip the connection before the chat begins
ライブチャット系アプリには、Apple Guidelineで定められた2つの要件がある。「接続前に相手の識別情報を表示すること」と「accept / decline の選択肢を用意すること」だ。
本番マッチのフローでは、これらは実装済みだった。マッチ演出のポップアップでニックネームと傾向を表示し、「会話を始める」か「今日はやめておく」を選べるようにしてあった。
問題は、テストモードだけがそのポップアップを経由していなかったことだ。
テストモードでは、開発中に動作確認しやすいよう、接続後に直接チャット画面へ遷移するルートが残っていた。レビュワーはテストモードでアプリを試す。彼らが見たのは「情報表示なし、選択肢なし、いきなりチャット」という体験だった。
// 核心
テストモードがアプリの審査になる。
レビュワーは本番の接続を観測できない。実際に接続が成立するまで待てないし、ランダムな相手が誰であるかも確認できない。だから彼らはテストモードを使う。
テストモードを「開発用の近道」として作ると、そのショートカットが審査の全体評価になる。テストモードのユーザー体験と本番のユーザー体験は、完全に一致させなければならない。
対応は、テストモードと本番を同じフローに統一することだった。テストマッチが成立したあとも、本番と同じポップアップを経由してチャットに入る。レビュワーが体験するフローが、一般ユーザーが体験するフローと同じになった。
// 学び
テストモードは「通過させるための抜け道」ではなく、「アプリの実態を正確に見せる窓口」として設計する。安全要件・UX要件・フロー要件は、テストモードにも本番と同じ水準で適用する。Timeline
2回のリジェクトの流れ。
// 現時点での気づき
審査は、コードだけじゃない。
まだ通っていないので「学んだ」と断言はできないが、2回の指摘を受けて感じたことはある。審査が見ているのはコードの動作だけではない。メタデータの言葉遣い、レビュワーが実際に体験するフロー、そしてそのフローがガイドラインの要件を満たしているか。
「自分のアプリは要件を満たしている」と思っていても、レビュワーが見る画面でそれが伝わっていなければ意味がない。テストモードの設計は、そのまま審査の設計だ。続報はまた書く。