iOSAndroidApp StoreGoogle PlayRelease

App Store / Google Play のリジェクト事例集と審査を通すための実践チェックリスト

Sloth255
Sloth255
·22 min read·4,918 words

アプリをリリースしようとして、レビューで差し戻される。これは多くの開発者が一度は経験する壁です。

しかも、審査で止まる理由はクラッシュやビルド不備だけではありません。権限説明、プライバシーポリシー、課金導線、ストアメタデータ、審査コメントの不足など、実装以外の運用面が原因になることも珍しくありません。

本記事では、App Store と Google Play の審査で起きやすいリジェクト事例をカテゴリ別に整理し、申請前に確認したいポイントを実務目線でまとめます。


対象読者

  • 初めて App Store / Google Play にアプリを申請する方
  • 過去にリジェクトされた経験があり、原因を整理したい方
  • React Native / Flutter などクロスプラットフォームで開発している方
  • リリース前のチェックリストを整備したいチーム

先に押さえたい用語

記事の途中で出てくる用語を先に短く整理しておきます。ここを押さえておくと、後半のリジェクト事例が読みやすくなります。

  • reviewer: Apple や Google の審査担当者。アプリ本体だけでなく、ストア説明文、スクリーンショット、申告情報、審査コメントまで含めて確認する
  • IAP (In-App Purchase): Apple のアプリ内課金。デジタルコンテンツやアプリ内機能の販売で使う仕組み
  • ATT (App Tracking Transparency): 他社アプリや Web サイトをまたいだトラッキング前に、ユーザーへ許可を求める iOS の仕組み
  • IDFA: 広告計測で使われる識別子。これを使う構成だと ATT や App Privacy の確認が必要になりやすい
  • Data safety / App Privacy: Google Play / App Store で行うデータ収集の自己申告。SDK を追加したのに申告を更新していないと整合性が崩れる
  • target SDK: Android アプリがどの API レベル前提で動くかを示す値。minSdkVersion は「最低対応 OS」であり、意味が違う
  • ストアメタデータ: スクリーンショット、説明文、サブタイトル、カテゴリ、年齢レーティング、申告項目など、ストア上に表示・提出する情報全体
  • WebView: アプリ内に Web ページを表示する部品。便利だが、画面の大半を WebView に頼るとネイティブ価値が薄く見えやすい
  • UGC (User Generated Content): ユーザー投稿コンテンツ。コメント、画像投稿、プロフィール、レビューなどが含まれる
  • restore purchases: 以前購入した課金状態を復元する導線。サブスクや買い切り機能の復元確認で重要になる
  • entitlement: Apple の Capability や特定機能を利用するための権限設定。多くは通常のアプリでも使えるが、一部の特別な entitlement は Apple の承認や追加条件が必要になる

まず理解したい審査側の視点

リジェクトを減らすには、ガイドラインを読むだけでは足りません。審査担当者が何を短時間で確認しているかを理解した方が、対策の優先順位を付けやすくなります。

特に止まりやすいのは、次のような状態です。

  • 実装はあるが、説明が不足している
  • 権限を要求しているが、機能との関係が見えない
  • 課金があるのに、価格や解約導線が曖昧
  • スクリーンショットや説明文と、実際のアプリが一致していない
  • reviewer がログインできず、主要機能を確認できない

レビューでは UI の美しさより前に、安全性・整合性・完成度が見られます。

観点 見られること よくある差し戻し
完成度 クラッシュしないか、未実装がないか 起動直後クラッシュ、プレースホルダー放置
プライバシー データ収集と説明が一致しているか 権限説明不足、Privacy URL なし
課金 課金ルールに従っているか 外部決済誘導、サブスク説明不足
メタデータ ストア情報と実装が一致しているか スクリーンショット詐称、申告ミス
審査導線 reviewer が確認しやすいか ログイン不可、検証手順不足

App Store と Google Play の違いを先に整理する

どちらも「安全で、誤解がなく、未完成ではないこと」を見ていますが、止まりやすい論点には少し差があります。

観点 App Store で強く見られやすい点 Google Play で強く見られやすい点
完成度 UI の自然さ、未完成感、クラッシュ 実装不備に加え、申告内容とのズレ
プライバシー 権限説明文、ATT、App Privacy permissions、Data safety、広告申告
課金 IAP ルール、Reader App 条件、サブスク表記 誇大表示や不明瞭な課金説明、定期購入の明確性
技術要件 審査中の挙動、実機での安定性 target SDK、危険権限、SDK ポリシー適合
運用面 reviewer が確認できるか Console 側の宣言、closed testing、production access gate

ざっくり言うと、App Store は「アプリ体験と課金・プライバシーの説明の厳密さ」で止まりやすく、Google Play は「技術要件と自己申告の整合」で止まりやすいです。

そのため、同じアプリでも対策の順番は少し変わります。

  • App Store: 実機挙動、課金画面、権限文言、審査コメントを先に詰める
  • Google Play: target SDK、permissions、Data safety、広告申告を先に詰める

実際の差し戻し・公開ブロック文面から見るケーススタディ

ここでは、実際に見かけやすい App Store の審査文面と、Google Play の公開ブロック要件文面を引用しながら、「その一文が何を意味しているか」と「最初に何を直すべきか」を整理します。後半の各カテゴリはこのケースの詳細解説として読むと使いやすいです。

Case 1: App Store で起動直後にクラッシュ

"We discovered one or more bugs in your app when reviewed on iPhone running iOS 17.0 on Wi-Fi. Specifically, the app crashed immediately upon launch."

これは単なる一時的失敗ではなく、審査端末で再現する重大不具合として扱われます。最初にやることは、機内モード、初回インストール、空アカウント、低速回線で再現確認し、起動直後に走る処理を洗い出すことです。

Case 2: App Store で Privacy Policy が不足

"Your app collects user or usage data but does not have a privacy policy URL."

これは SDK や独自 API を通じて何らかのデータを扱っているのに、ユーザーが確認できる公開説明が不足している状態です。最初にやることは、公開 URL を 1 つ用意し、収集データ、利用目的、第三者提供、問い合わせ先を明記したうえで、App Store Connect の設定と App Privacy をそろえることです。

Case 3: App Store でデジタル課金が IAP になっていない

"Your app includes the ability to purchase digital content, but the purchase mechanism does not use in-app purchase."

これは価格表示の問題ではなく、売り物の性質に対して課金方式が誤っているという指摘です。最初にやることは、何を売っているかを機能単位で分解し、アプリ内で消費されるデジタル価値なら IAP 前提へ寄せることです。

Case 4: Google Play で target API 要件を満たしていない

"When you publish a new app, you must target Android 15 (API level 35) or higher."

Google Play は classic な rejection mail だけでなく、提出前の要件ブロックとして条件を表示することがあります。この文面が出たら、アプリ品質以前に公開要件未達です。最初にやることは、targetSdkVersion だけでなく、依存ライブラリ、権限差分、通知やバックグラウンド動作まで含めて更新計画を立てることです。

Case 5: Google Play の新規 personal account で production に進めない

"You must run a closed test for your app with a minimum of 12 testers who have been opted-in for at least the last 14 days continuously."

初回公開では、アプリの出来とは別に account 種別由来の production gate で止まることがあります。新しい personal account では closed test と production access の条件を満たさない限り、公開そのものに進めません。加えて、アカウント owner による Android 実機の device verification も必要になることがあります。

最初にやることは、対象アカウントが新しい personal account かを確認し、12 人・14 日の closed test、tester の継続 opt-in、Play Console mobile app を使った device verification を早めに完了することです。

App Store は審査コメントとして差し戻されることが多く、Google Play は Console 上の要件ブロックや申告差分として止まることが多いです。ただし本質は共通していて、多くは「未完成」「説明不足」「申告不一致」「公開要件未達」のどれかに分類できます。


カテゴリ1: アプリの完成度

1. 起動直後にクラッシュする

初回起動時の API エラー、ローカル DB 初期化失敗、nil 参照などは、もっとも典型的な差し戻し理由のひとつです。ここでいう nil 参照は、まだ値が入っていないオブジェクトを読みに行って落ちるパターンです。特に reviewer の端末環境は手元と完全には一致しないため、起動直後の安全性は過剰なくらい守った方がよいです。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onAppear {
                    setupApp()
                }
        }
    }

    private func setupApp() {
        do {
            try initializeDatabase()
        } catch {
            print("DB init failed: \(error)")
        }
    }
}

確認したいこと:

  • 初回起動時にアカウント未作成でもクラッシュしない
  • ネットワーク不通でも起動自体はできる
  • 必須データ取得に失敗しても、フォールバック画面へ遷移できる

解決策として有効なのは、起動処理を次の 2 種類に分けることです。

  • 絶対に成功しないと表示できない処理
  • 失敗しても後からリトライできる処理

たとえば、リモート設定の取得やおすすめ一覧の先読みでアプリ全体を止める必要はありません。まずはホーム画面や最低限の骨組みを表示し、失敗した処理だけ再試行できる形にすると、審査環境差分で落ちにくくなります。

実務では次の順番で直すと早いです。

  • クラッシュログを取得する
  • 起動時に実行している初期化処理を列挙する
  • 同期で必須な処理を減らす
  • 機内モード、初回インストール、空データの状態で実機確認する

2. 機能が未実装、またはプレースホルダーが残っている

「Coming Soon」と表示するだけの画面、押しても何も起きないボタン、切れたリンクは、未完成アプリと判断されやすいポイントです。

申請直前は機能追加よりも、次を優先して潰す方が安全です。

  • 導線だけある未実装機能を削除する
  • ダミーテキストやテスト文言を消す
  • エラー画面や空状態の表示を最低限整える

3. ログインしないと何も確認できない

ログイン必須アプリでも、reviewer が主要機能に到達できなければ差し戻しになりやすくなります。

必要なのは、単なるアカウント情報ではなく、最短で確認できる導線です。

  • デモアカウントを用意する
  • 2FA が必要なら手順を書く
  • 特定ロールでしか見えない機能があるなら補足する
  • サンドボックスデータが必要なら初期状態を説明する

対処の基本は「審査担当者が最短距離で価値を確認できる状態」を作ることです。理想は、会員登録や問い合わせなしで主要画面を確認できる read-only の審査用アカウントを用意することです。

ここでいうサンドボックスデータは、本番ユーザーに影響しない審査・検証用のダミーデータです。注文履歴、投稿、サブスク状態、地図上の店舗データなど、空だと価値が伝わらない情報を事前に入れておくとレビューしやすくなります。

もし SMS 認証や招待制があるなら、そのまま reviewer に丸投げしない方が安全です。

  • 有効期限の長い審査用アカウントを発行する
  • 2FA が必要ならバックアップコードや代替手順を添える
  • 初期データが空だと価値が伝わらないなら、テスト用データを事前投入する
  • 後述の「申請コメントに書くべきこと」のテンプレートで到達手順まで書く

カテゴリ2: プライバシーと権限

4. プライバシーポリシー URL がない

ユーザーデータや利用状況データを扱うのに、Privacy Policy の URL がない状態は非常に危険です。これはアプリ本体の問題というより、申請情報の不備として止まります。

最低限、次の内容はプライバシーポリシーに明記しておきたいです。

  • 収集するデータの種類
  • 利用目的
  • 第三者提供の有無
  • 保持期間
  • ユーザーの削除・訂正依頼手段

ここで混同しやすいのが、Privacy PolicyApp Privacy / Data safety は別物だという点です。

  • Privacy Policy: ユーザーが読める公開文書
  • App Privacy / Data safety: ストアに提出する自己申告

どちらか一方だけでは不十分で、内容が一致している必要があります。

解決策としては、まず 1 枚の公開ページを用意し、そこに「何を集めるか」「何に使うか」「問い合わせ先」を書くのが最短です。そのうえで、使っている SDK 一覧と見比べながら App Store Connect / Play Console の申告を更新します。

5. 使っていない権限を要求している

位置情報、連絡先、マイク、カメラなどの権限は、機能と強く結び付いていないと不信感を持たれます。ライブラリを入れた結果、不要な権限が混入しているケースも多いです。

import { Alert } from 'react-native'
import * as Location from 'expo-location'

async function requestLocationForMap() {
  const { status } = await Location.requestForegroundPermissionsAsync()
  if (status !== 'granted') {
    Alert.alert('近くの店舗を地図に表示するには位置情報の許可が必要です')
    return
  }

  // 地図表示処理
}

ポイントは、使う権限だけを、使う瞬間に要求することです。

解決策のコツは、権限をコード上で探すだけでなく、依存ライブラリ由来の宣言も確認することです。Android では AndroidManifest.xml、iOS では Info.plist と導入済み SDK を合わせて見ないと、意図しない権限が残りやすくなります。

6. 権限説明文が抽象的すぎる

「より良い体験のために使用します」のような説明では、何のための権限かが伝わりません。説明文は、具体的な機能に結び付いている必要があります。

よい例:

  • 近くの店舗を地図上に表示するため
  • プロフィール画像を撮影するため
  • バーコードを読み取るためにカメラを使用するため

弱い例:

  • 体験向上のため
  • 利便性向上のため
  • サービス品質改善のため
<key>NSLocationWhenInUseUsageDescription</key>
<string>近くの店舗を地図に表示するために使用します</string>

<key>NSCameraUsageDescription</key>
<string>プロフィール写真を撮影するために使用します</string>

7. App Tracking Transparency に未対応

IDFA を使う場合は、ATT ダイアログと App Privacy の申告整合が必要です。トラッキング許可を得られない前提で機能する設計にもしておくべきです。

ここでいう ATT は、広告計測や attribution で使われる IDFA へのアクセス前に、ユーザーへ許可を求める仕組みです。つまり、「広告 SDK を入れた」「計測 SDK が IDFA を読む」「他社データと結び付けてユーザーを追跡する」といった構成では審査対象になりやすい、という理解で十分です。

import AppTrackingTransparency

func requestTrackingPermission() {
    ATTrackingManager.requestTrackingAuthorization { status in
        switch status {
        case .authorized:
            break
        case .denied, .restricted, .notDetermined:
            break
        @unknown default:
            break
        }
    }
}

修正の進め方としては、次の順番が現実的です。

  • どの SDK が IDFA や tracking を使うか棚卸しする
  • 本当に tracking が必要か見直す
  • 不要なら SDK 設定や依存関係を削って ATT 自体を不要にする
  • 必要なら ATT ダイアログ、App Privacy、アプリ内説明の整合を取る
  • 許可されなくても主要機能が動くことを確認する

カテゴリ3: 課金とビジネスモデル

8. デジタルコンテンツを外部決済へ誘導している

アプリ内のデジタル商品や機能課金を扱う場合、App Store では IAP の利用が基本です。Web 決済や外部サイト購入へ誘導すると、高確率で止まります。

整理すると、次の理解が重要です。

  • 物理商品や対面サービスは外部決済でもよい
  • デジタルコンテンツやプレミアム機能は IAP が原則
  • Reader App で外部サイトへのアカウント作成・管理リンクを出すには External Link Account Entitlement が必要
  • Reader App の例外がある場合でも、対象カテゴリと実装条件はかなり限定的

IAP を使うべきか迷うときは、「アプリの中で消費されるデジタル価値か」を基準にすると整理しやすいです。

  • IAP 寄り: 広告非表示、プレミアム機能、ゲーム通貨、記事読み放題、動画見放題
  • 外部決済でもよいことが多い: 物理商品、配車、対面レッスン、飲食デリバリー、宿泊予約

すでに外部課金へ誘導していて止まった場合は、次のどれかに寄せる必要があります。

  • IAP 前提の課金設計へ組み替える
  • 本当に Reader App 条件に当てはまるかを精査する
  • デジタル商品と物理サービスを分離し、アプリ内導線を整理する

9. サブスクリプションの説明が弱い

サブスクリプションでは、価格、更新周期、自動更新、解約導線が曖昧だとユーザー保護の観点で弱く見られます。

課金画面やストア説明には、少なくとも次が必要です。

  • プラン名、期間、提供内容が分かる
  • 総請求額が明示されている(年額なら年額が最も分かりやすく表示されている)
  • 更新周期と自動更新であることが分かる
  • 無料トライアル後の通常課金額が分かる
  • Terms of Service と Privacy Policy へのリンクがある
  • 既存購読者向けの sign in または restore purchases 導線がある
  • 解約方法が分かる

よくある失敗は、「月額換算だけを大きく見せて、実際の請求額や更新条件が分かりにくい」パターンです。年額プランなら、年額総額が一目で分かるようにし、その下に補助的に月額換算を書く方が安全です。

解決策としては、購読画面を次の要素で見直すと整理しやすいです。

  • プラン名
  • 請求タイミング
  • 総請求額
  • 無料トライアル後の通常価格
  • 復元導線
  • 利用規約とプライバシーポリシー
  • 管理画面または解約導線

たとえば「7 日間無料、その後年額 7,200 円で自動更新」のように、無料期間の後に何が起きるかまで 1 文で読める状態にしておくと、審査でも誤解されにくくなります。

さらに、審査で止まりにくい購入画面にするには、ユーザーが迷いやすい論点を画面内で潰しておくと効果的です。

  • どのプランが選ばれているか
  • いま請求される金額はいくらか
  • 無料期間終了後はいくらになるか
  • いつまでに解約すれば次回課金が止まるか
  • 既存購読者はどこから復元できるか
// React Native 単体では StoreKit の system-provided UI を直接開けないため、
// iOS ネイティブ実装をブリッジできない場合のフォールバック例。
import { Linking, Text, TouchableOpacity } from 'react-native'

function SubscriptionSettings() {
  return (
    <TouchableOpacity
      onPress={() => Linking.openURL('https://apps.apple.com/account/subscriptions')}
    >
      <Text>サブスクリプションを管理</Text>
    </TouchableOpacity>
  )
}

iOS ネイティブ実装が可能なら、Apple が案内している showManageSubscriptions(in:) を使って system-provided management UI を開く方が自然です。

10. Reader App 例外を広く解釈しすぎる

Reader App の例外は便利に見えますが、対象はかなり限定されています。主機能が 雑誌、新聞、書籍、音声、音楽、動画 のいずれかであり、外部で購入済みのコンテンツやサブスクリプションをアプリ内で閲覧・再生する形が前提です。

さらに、外部サイトへのアカウント作成・管理リンクを出すには External Link Account Entitlement が必要です。iOS / iPadOS / tvOS で IAP を提供しているアプリはこの entitlement の対象外なので、「Reader App だから外部課金へ自由に誘導できる」という理解は誤りです。

動画、音楽、書籍などの消費型コンテンツと、アプリ機能やゲーム内通貨では扱いが異なります。自分のアプリがどのカテゴリに属するかを曖昧にしたまま申請すると、判断が割れやすくなります。

迷う場合は「売っているものはコンテンツか、機能か」「購入導線はどこにあるか」を整理し、ストア説明や審査コメントでも補足した方が安全です。

解決策としては、申請前に次の 3 点を Yes / No で確認すると判断しやすくなります。

  • 主機能は本当に雑誌、新聞、書籍、音声、音楽、動画の提供か
  • 外部で購入済みのコンテンツを閲覧させる構造か
  • iOS 側で IAP を提供していないか

この 3 つのうちどれかが曖昧なら、Reader App 例外前提で設計しない方が安全です。


カテゴリ4: デザインと体験品質

11. プラットフォームの期待から大きく外れた UI

完全に独自のナビゲーション体系、戻る導線の不在、読みづらいコントラストなどは、使いにくさとして評価を落とします。見た目の独自性より、プラットフォームの期待に沿った操作性を優先した方が審査では有利です。

12. WebView でラップしただけに見える

実質的に Web サイトをそのまま表示しているだけのアプリは、ネイティブ体験としての価値が弱いと見なされることがあります。

危険なパターン:

  • ほぼ全画面が WebView
  • ネイティブ固有機能がない
  • オフライン時に何もできない
  • 端末連携や通知など、アプリならではの価値がない

単なるラッパーに見せないためには、共有、通知、カメラ、ローカル保存、オフライン UX など、端末統合の価値を明確にした方がよいです。

WebView は悪ではありません。問題なのは「ネイティブアプリとして提出しているのに、中身が実質サイトそのまま」に見えることです。もし WebView を使うなら、少なくとも次のどれかはネイティブ側で価値を出したいです。

  • ネイティブのナビゲーションや設定画面
  • 共有、通知、カメラ、ファイル保存などの端末機能
  • オフライン時の説明やキャッシュ表示
  • Web 側にはないアプリ専用の操作体験

13. 広告や課金導線が過剰

コンテンツより広告が目立つ、誤タップを誘う配置、閉じにくい interstitial の多用は、審査だけでなく評価低下にも直結します。収益化導線は存在してよいですが、体験を壊していないかを実機で見直す必要があります。


カテゴリ5: ストアメタデータと申告情報

審査ではアプリ本体だけでなく、ストアの説明文や申告内容も見られます。ここが実態とズレていると、実装が正しくても止まります。

見直したい項目:

  • スクリーンショット
  • アプリ説明文
  • サブタイトル
  • 年齢レーティング
  • App Privacy / Data safety
  • 広告の有無申告

特に危険なのは、実装していない機能を説明文に書くことです。将来実装予定の機能を先に掲載するのも避けた方が安全です。


カテゴリ6: UGC と高リスクカテゴリ

14. UGC があるのにモデレーション導線がない

ユーザー生成コンテンツを扱う場合、投稿機能があるだけでは不十分です。最低限、次の導線は用意したいです。

  • 通報機能
  • ブロック機能
  • 利用規約
  • 問い合わせ窓口
  • 違反コンテンツの対応方針

UGC があるのに防御策が見えないと、審査側から運用リスクを懸念されやすくなります。

15. 健康・金融・子ども向けカテゴリで説明責任が足りない

医療・健康、金融・投資、子ども向け、位置情報常用アプリは、一般カテゴリより厳しく見られます。正確性、法令順守、誤解の余地がない説明、問い合わせ先の明示など、通常より高い基準を想定した方がよいです。

特にこの種のカテゴリでは、「便利そうだから入れた説明文」が逆効果になることがあります。健康や投資に関する表現は、効果保証、誤認、過剰な期待を招かない書き方に寄せる必要があります。

実務上は、次の観点で見直すと事故を減らせます。

  • 医療や健康: 診断・治療を断定していないか
  • 金融: 利益保証や過度な期待を煽っていないか
  • 子ども向け: 外部リンク、広告、課金導線が強すぎないか
  • 位置情報常用: 常時取得が本当に必要か、代替手段はないか

このカテゴリでは、機能追加より「言い過ぎていないか」「説明責任を果たせているか」の確認の方が重要です。


よくあるリジェクト文言の読み解き方

審査メッセージは短く抽象的なことが多く、そのまま読むと何を直すべきか分かりにくいです。実際には、次のように読み替えると動きやすくなります。

審査メッセージの傾向 実際に疑われていること 最初にやること
App Completeness 未完成、クラッシュ、導線切れ 起動動画を撮り、押せないボタンや空画面を洗い出す
Your app requests access... 不要権限、説明不足 その権限が必要な画面と説明文を 1 対 1 で対応付ける
Metadata does not reflect... スクリーンショットや説明文の不一致 ストア説明、画像、実装差分を並べて確認する
Use in-app purchase デジタル課金の外部誘導 何を売っているかを整理し、IAP 前提へ寄せる
Target API level Android 提出要件未達 target SDK と依存ライブラリを更新して再試験する
Data safety form is inaccurate 申告と SDK 実装のズレ SDK 棚卸しを行い、Console 申告を更新する

ここで重要なのは、審査文言を仕様書のように読むことです。抽象的に見えても、多くは「未完成」「説明不足」「申告不一致」のどれかに分類できます。


Google Play で見落としやすい項目

新しい personal account の初回公開要件

初めて Google Play に出す読者向けに、ここは特に重要です。新しく作成した personal developer account では、アプリ内容とは別に production 公開へ進むための account 要件があります。

代表的なのは次の 2 点です。

  • closed test に 12 人以上の tester が継続して参加していること
  • Play Console mobile app を使った Android 実機の device verification を完了していること

これは classic な「リジェクトメール」というより、Play Console 上で production へ進めないブロックとして効きます。つまり、アプリが完成していても account 側の条件を満たしていなければ公開できません。

初回公開で詰まりやすいポイントは次のとおりです。

  • tester 数は足りているが、14 日間の継続 opt-in 条件を満たしていない
  • tester が参加しただけで、実際の利用やフィードバックが薄い
  • account owner が実機 verification を終えていない
  • internal test だけで十分だと思ってしまい、closed test 条件を見落とす

初回公開なら、実装確認と並行してこの要件を最初に潰しておく方が安全です。

target SDK の追従漏れ

Google Play の target API レベル要件は継続的に更新されます。執筆時点の最新値ではなく、申請時点の最新要件を Play Console で確認する運用が必要です。

ここで混同しやすいのが、targetSdkVersionminSdkVersion の違いです。

  • targetSdkVersion: 新しい Android の仕様にどこまで対応する前提か
  • minSdkVersion: どこまで古い Android をサポートするか

つまり、minSdkVersion を上げていなくても、Google Play 提出要件の観点では targetSdkVersion が不足しているだけで止まります。

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    defaultConfig {
        targetSdkVersion rootProject.ext.targetSdkVersion
        minSdkVersion 24
    }
}

対応策としては、数字を書き換えるだけで終わらせないことが重要です。target SDK を上げると、権限モデル、バックグラウンド制限、通知挙動、foreground service、ファイルアクセスなどが変わることがあります。更新時は次をまとめて確認します。

  • Android Gradle Plugin と依存ライブラリの対応状況
  • 権限ダイアログの挙動差分
  • 通知やバックグラウンド処理の制限
  • 主要端末での実機テスト

危険な権限が残っている

使用していない危険権限が manifest に残っていると、それだけで説明責任が発生します。特に CONTACTS、CALL_LOG、SMS、READ_PHONE_STATE などは慎重に見直した方がよいです。

<!-- 使わない権限は宣言しない -->
<!-- <uses-permission android:name="android.permission.READ_CONTACTS" /> -->
<!-- <uses-permission android:name="android.permission.READ_CALL_LOG" /> -->

Data safety と実装が一致していない

Analytics SDK や広告 SDK を追加したのに、Console 側の申告が古いままというケースは意外と多いです。SDK を入れ替えたタイミングで、Data safety も更新対象に含める運用が必要です。

Data safety は「このアプリはどのデータを集め、共有し、何に使うか」を Google Play に申告する欄です。Apple 側の App Privacy も考え方は近く、実装とズレると信用を落とします。

解決策としては、感覚で書かずに棚卸しするのが一番安全です。

  • 入っている SDK を列挙する
  • それぞれが扱うデータ種別を確認する
  • 自前 API が送っているデータも洗い出す
  • Play Console / App Store Connect の申告と突き合わせる
  • 変更があったらプライバシーポリシーも更新する

権限は「使う瞬間」に要求する

起動直後に複数の権限ダイアログをまとめて出す設計は、ユーザーにも reviewer にも悪い印象を与えやすいです。

よりよい方針は次のとおりです。

  • 機能到達時に権限を要求する
  • 直前に短い pre-permission 説明を入れる
  • deny 時の代替導線を用意する

これは審査対策だけでなく、許可率の改善にも効きます。


申請コメントに書くべきこと

審査コメント欄は軽視されがちですが、reviewer の迷いを減らす重要な場所です。特にログイン必須アプリ、権限利用アプリ、外部デバイス連携アプリでは効果が大きいです。

書くとよい内容:

  • デモアカウント情報
  • 主要機能へ到達する手順
  • 権限を使用する画面の説明
  • 2FA や特定ロールが必要な場合の補足
  • 外部サーバーやデバイス依存がある場合の補足

短いテンプレート例:

Review account:
Email: reviewer-demo@example.com
Password: xxxxxxxx

Main test flow:
1. Sign in with the review account
2. Open the Map tab to test location permission
3. Open Settings > Subscription to verify cancellation guidance

リジェクトされた後の対応方針

リジェクト時に重要なのは、感情的に反論することではなく、指摘内容を正確に分類することです。

進め方の基本は次の順番です。

  1. 指摘文をそのまま読み直す
  2. 再現条件を確認する
  3. 実装不備、説明不足、申告ミスのどれかに分類する
  4. 必要ならスクリーンショットや動画で補足する

本当に誤判定に見える場合でも、まずは説明不足を埋める方が早く解決することが多いです。異議申し立ては最後の手段として考える方が実務的です。

実際の返信では、長い言い訳よりも「何を直したか」を短く明確に書く方が通りやすいです。

Thank you for the review.

We identified the issue as [implementation / metadata / clarification].
We made the following changes:
1. Fixed [issue]
2. Updated [metadata or review notes]
3. Added [account / explanation / screenshot]

How to verify:
1. Sign in with the review account
2. Open [screen name]
3. Tap [action]

If needed, we can provide additional screenshots or a screen recording.

日本語で整理すると、「原因」「修正内容」「確認手順」の 3 点だけで十分です。審査対応が長引くチームほど、この 3 点が混ざって会話しづらくなりがちです。

申請前 48 時間でやること

リリース前は機能追加の誘惑が強いですが、審査通過率を上げるなら直前は実装より確認に時間を使った方がよいです。

48 時間前

  • ストア説明文、スクリーンショット、年齢レーティング、Data safety / App Privacy を見直す
  • 使用中の SDK と権限一覧を棚卸しする
  • reviewer 用アカウントと審査コメントを準備する

24 時間前

  • iPhone 最新 OS、1 つ前の iOS、Android 複数機種で起動確認する
  • 機内モード、低速回線、初回インストール状態を試す
  • 課金、ログイン、権限要求、退会導線を通しで確認する

6 時間前

  • スクリーンショットと実アプリに差分がないか最後に見る
  • ストア申告と SDK 構成にズレがないか確認する
  • 審査コメントに到達手順と補足を書き切る

この 48 時間フローを毎回回すだけでも、リジェクト率はかなり下げやすくなります。

再発防止のための運用

一度通ったあとも、機能追加や SDK 変更で同じ論点が再発しやすいです。個人開発でもチーム開発でも、次の運用を置くと事故が減ります。

  • SDK を追加したら、権限・Data safety・App Privacy の更新をセットにする
  • ストア説明文に書く機能は、実装済みのものだけに限定する
  • 新しい権限を追加するときは、使用画面と説明文を PR で一緒に確認する
  • リリース前チェックリストを issue やテンプレートにして毎回使い回す
  • リジェクト文言と対応内容をチーム内に記録し、次回の審査コメントに活かす

審査対応を「毎回その場で考える作業」にしないことが、最終的には一番効きます。


申請前チェックリスト

提出先ごとに、そのまま使える形へ分けると漏れを見つけやすくなります。共通項目も、それぞれの表に含めています。

App Store 向け提出前チェックリスト

観点 確認項目 なぜ重要か
完成度 [ ] 最新 iOS と 1 つ前の主要バージョンで、初回起動・空データ・低速回線でもクラッシュしない App Completeness やクラッシュ指摘を防ぐ
審査導線 [ ] reviewer 用アカウント、到達手順、必要なら 2FA 手順を審査コメントに記載した reviewer が確認できないだけで差し戻しになる
権限 [ ] Info.plist の説明文が具体的な機能名に結び付いている 権限説明不足を避ける
プライバシー [ ] Privacy Policy の URL が公開済みで、App Store Connect に設定されている データ収集アプリの基本要件
申告整合 [ ] App Privacy の申告内容が SDK 構成と一致している 申告不一致を避ける
課金 [ ] デジタルコンテンツやアプリ機能の販売は IAP を使っている 外部決済誘導を避ける
サブスク [ ] プラン名、期間、総請求額、自動更新、無料トライアル後の価格、解約方法が購読画面で読める サブスク説明不足を避ける
購読者導線 [ ] Terms of Service / Privacy Policy のリンクと、restore purchases または sign in 導線がある 既存購読者の導線不足を避ける
ATT [ ] IDFA や tracking を使う場合、ATT と App Privacy の整合が取れている Tracking 関連の差し戻しを防ぐ
メタデータ [ ] スクリーンショット、説明文、サブタイトルが現在の実装と一致している metadata mismatch を避ける

Google Play 向け提出前チェックリスト

観点 確認項目 なぜ重要か
初回公開要件 [ ] 新しい personal account の場合、12 人以上・14 日以上の closed test 条件を満たしている production access に進めないブロッカーを避ける
アカウント確認 [ ] 新しい developer account の場合、account owner が Android 実機の device verification を完了している 公開前の account gate を避ける
完成度 [ ] Android 複数機種で、初回起動・オフライン・空データ時の挙動を確認した 実装不備や pre-review check の検出を減らす
技術要件 [ ] targetSdkVersion が申請時点の要件を満たしている 提出要件未達を避ける
配布設定 [ ] 64-bit 対応を含むビルド設定と依存ライブラリの互換性を確認した 配布時の技術要件違反を避ける
権限 [ ] 危険権限は本当に必要なものだけを残し、必要性を説明できる permissions と機能の不一致を避ける
プライバシー [ ] Privacy Policy が公開済みで、Play Console の設定と一致している データ取り扱いの説明不足を避ける
申告整合 [ ] Data safety、広告申告、年齢設定が現在の SDK 構成と一致している Console 側の申告不一致を避ける
ログイン導線 [ ] reviewer が主要機能へ到達できるアカウントや手順を用意した 実機確認不能による差し戻しを避ける
課金 [ ] 定期購入や課金導線の価格、更新条件、解約方法が分かりやすい 誤認を招く課金 UI を避ける
ストア情報 [ ] ストア説明文、スクリーンショット、カテゴリ設定が実装と一致している listing mismatch を避ける
SDK 運用 [ ] SDK を追加・削除した差分が Data safety と permissions に反映されている 後追いの修正依頼を避ける

まとめ

アプリ審査で止まりやすいのは、単純なバグよりも、実装と説明のズレ運用面の詰め不足です。

特に重要なのは次の 4 点です。

  • reviewer が迷わず主要機能を確認できること
  • 権限とデータ収集の理由が具体的に説明されていること
  • 課金ルールとストア申告が正しく整っていること
  • ストアメタデータと実装が一致していること

リリース直前ほど機能追加をしたくなりますが、審査通過率を上げるうえでは、最後の 1 日をチェックリスト消化に使う方が効果的です。


参考リンク