僕が運営しているAI写真変換アプリ「Morphica」には、生成した画像をみんなで見せ合う「みんなの投稿」機能がありました。

何ヶ月も前のバージョンから実装していて、その間のアップデート審査は何度も通過してきた機能です。それが2026年7月24日、通常のアップデート審査(v1.1.4)で突然リジェクトされました。指摘はGuideline 1.2 — User Generated Contentの安全対策不足

この記事は、そこから2日で審査を通すまでにやったこと — 安全対策のフル実装と、それでも最後に下した「機能ごと消す」という判断 — の全記録です。同じ指摘を受けた人がそのまま使えるように、実装リストごと公開します。

この記事で分かること

  • 一度通った機能が、後から審査に引っかかることは普通にあるという実例
  • AppleがUGC機能に求める安全対策の具体的な中身(実装リスト付き)
  • 「全部実装する」と「機能を消す」を天秤にかけ、再審査を2日で通した判断の過程

何が起きたか

  • 2026-07-24: v1.1.4(ビルド17)が審査でリジェクト。指摘はGuideline 1.2 — 「匿名投稿に対する安全対策が不十分」。あわせて年齢制限を18+にすることも要求された
  • 「みんなの投稿」機能自体はずっと前のバージョンから存在し、これまでの審査では一度も指摘されていない
  • 2026-07-26: 対応したビルド18が審査合格、配信開始

まず強調したいのはここです。審査は「今回のアップデートの差分」を見ているのではなく、毎回アプリ全体を見ています。 既存機能だから安全、前回通ったから安全、という保証はどこにもありません。体感としては、2026年に入ってSNS的な投稿機能への審査基準が厳しくなった印象もあります(あくまで一開発者の推測です)。

まず正攻法: 安全対策をフル実装した

リジェクト当日、まずAppleの要求に真正面から応える準備をしました。Guideline 1.2がUGCに求めるのは、要するに「不適切な投稿からユーザーを守る仕組み一式」です。実装したのは以下の7点。

  1. 投稿時の規約同意ゲート — 公開ダイアログにゼロトレランス方針の告知と利用規約への同意チェック(必須)を追加
  2. 利用規約にゼロトレランス条項を追加 — 不適切投稿への対応方針と24時間対応、連絡先を日英で明記
  3. 通報の即時自動非表示 — 通報された投稿はDBトリガーで即is_hidden=TRUE。運営のレビューを待たずフィードから消える
  4. ユーザーブロック機能 — ブロックしたユーザーの投稿はRLSでフィードから除外
  5. BAN基盤 — 違反ユーザーは全投稿非表示+新規投稿拒否
  6. 生成時フィルタの強化 — AI生成側のセーフティ設定を一段厳しく変更
  7. 運用SOPの整備 — 「通報から24時間以内にレビューし、違反なら削除+BAN、誤通報なら復元」という手順書を作成

ポイントは3の「通報=即時非表示」です。Appleの要求は「24時間以内の対応」ですが、トリガーで先に消しておけば、ユーザー保護の観点では常に対応済みの状態から運用が始まります。個人開発は運営も1人なので、「人間の対応速度に依存しない設計」にできるところはDB側に寄せるのが現実的です。

それでも、機能ごと消すことにした

安全対策一式を実装した上で、最終判断は「コミュニティ機能をまるごと非表示にして再提出」でした。

決め手は2つあります。

1. 18+の年齢制限が重すぎた

指摘には年齢制限18+化の要求が含まれていました。投稿機能のためにアプリ全体が18+になると、本来のメイン機能(写真のAIスタイル変換)まで巻き添えでダウンロードの間口が狭まります。

2. 数字を見たら、判断は明快だった

直近1週間のKPIは、コミュニティ閲覧23回・投稿1件。アプリの価値のほぼすべてはAI変換側にあり、投稿機能はまだ「育っていない芽」でした。育っていない芽のために、審査リスクと18+化を背負う理由がない — 数字がそう言っていました。

消し方が大事: 削除ではなくフィーチャーフラグ

「消す」と言っても、コードは1行も削除していません。

// feature_flags.dart
class FeatureFlags {
  static const communityEnabled = false;  // これだけ
}

このフラグで、ナビのタブ・投稿ボタン・コミュニティ画面への導線をまとめて非表示にしました。実装した安全対策一式もコードベースにそのまま残っています。再開する日が来たら、フラグをtrueに戻すだけです。

もう1つ細かい配慮として、公開済み画像の「取り下げボタンだけは残しました」。機能を消しても、過去に投稿したユーザーが自分のデータを回収する手段は残す — ここは消してはいけない部分です。

さらに、旧バージョン(審査に出す前のv1.1.3)では投稿機能がまだ生きているため、実装した通報・BAN基盤のマイグレーションは本番DBに先行適用しました。新ビルドのためではなく、今この瞬間に旧バージョンを使っているユーザーの保護のためです。

再提出時には、App Store Connectのメッセージ欄で「UGCが存在しないビルドにはGuideline 1.2は適用されず、18+要求も根拠を失う」というロジックを添えて送信。2日後、審査に合格しました。

この件から学んだこと

  • 審査は毎回、アプリ全体を見る — 「前回通ったから安全」はない。既存機能も次の審査で再評価される前提でいる
  • UGCは「機能」ではなく「運営責任のセット」 — 投稿機能を付けた瞬間、規約・通報・ブロック・24時間対応の義務がついてくる。実装コストではなく運営コストで判断する
  • 機能はkill switchつきで作る — フィーチャーフラグで包んでおけば、「消す」が最速の選択肢になる。リジェクト対応で一番効いたのは、この設計だった
  • 数字が判断を軽くする — 利用データがあれば「思い入れ」と「実態」を切り分けられる。閲覧23・投稿1という数字がなければ、もっと悩んでいたはず
  • 撤去するときも、ユーザーのデータ回収手段は残す — 取り下げボタンは消さない。信頼はこういう細部に宿る

まとめ

  • 何ヶ月も審査に通っていたUGC機能が、ある日突然Guideline 1.2でリジェクトされた
  • 安全対策(同意ゲート・通報即時非表示・ブロック・BAN・24h SOP)を全部実装した上で、18+要求とKPIを天秤にかけて機能ごと非表示を選んだ
  • 実装はフラグで残してあるので、再開はいつでもできる
  • UGCを付けるか迷っている人へ: 上の安全対策リストが「入場料」です。それでも付けたい機能かどうか、先に考えておくと審査で慌てません

なお、iOS審査の落ちやすいポイント全般は審査リジェクト理由TOP10の記事にまとめています。この記事はその「1.2」の実例編でした。