React Native副業でApp Store審査に落ちる原因TOP5と事前チェックリスト
結論:審査リジェクトの8割は「事前チェック不足」で防げる
React Nativeで副業アプリを開発し、いざApp Storeに申請したら審査でリジェクト——これは副業エンジニアが最もよく踏む地雷のひとつです。クライアントへの納期が迫っているときほどダメージが大きく、信頼にも直結します。
筆者が過去に関わった10件以上のiOSアプリ副業案件のなかで、審査リジェクトを経験したものは6件。そのうち5件はリジェクト理由が被っていました。つまりパターンを知っていれば、ほぼ確実に回避できます。
以下では頻出原因TOP5を実例と修正手順つきで解説し、最後にそのまま使えるチェックリストを載せています。
TOP5:React Native副業案件でApp Store審査に落ちる原因
1位|プライバシーポリシーが存在しない or URLが無効
もっとも多いリジェクト理由です。Appleのガイドライン(5.1.1)は、個人情報を一切収集しないアプリでも、プライバシーポリシーへのリンクをApp Store Connectに登録することを求めています。
よくある失敗パターン:
- クライアントがWebサイトを持っておらず、ポリシーページが存在しない
- ローカルIPや
localhostのURLをそのまま登録してしまった - Google Docs等のURLが「リンクを知っている人のみ閲覧可」になっておりApple側から見れない
修正手順:
termly.ioやprivacypolicygenerator.infoなどの無料ジェネレーターでポリシーを生成- クライアントの既存ドメインのサブパス(例:
https://example.com/privacy)に公開 - App Store Connectの「アプリ情報」→「プライバシーポリシーのURL」に登録
- ブラウザのシークレットモードでURLが開けるか確認
2位|位置情報・カメラ等の権限説明が不十分(NSUsageDescription)
iOSはInfo.plistにあるNSLocationWhenInUseUsageDescriptionやNSCameraUsageDescription等の説明文が、なぜその情報が必要なのかを具体的に説明していることを求めます。
React Nativeプロジェクトではapp.json(Expoの場合)やios/YourApp/Info.plistに記述しますが、下記のようなNG例が後を絶ちません。
// NG例(app.json Expo管理ワークフロー)
"ios": {
"infoPlist": {
"NSLocationWhenInUseUsageDescription": "位置情報を使います。",
"NSCameraUsageDescription": "カメラを使います。"
}
}
// OK例
"NSLocationWhenInUseUsageDescription": "近くの店舗を検索するために現在地を使用します。",
"NSCameraUsageDescription": "プロフィール写真を撮影するためにカメラを使用します。"
**「何のために使うか」を1文で書くだけで審査を通過できます。**抽象的な説明はガイドライン違反として弾かれます。
3位|デモアカウントが用意されていない(ログイン必須アプリ)
アプリにログイン機能があるにもかかわらず、App Store Connectの「審査に関する情報」にデモ用の認証情報を記入していないとリジェクトされます。Appleのレビュアーはアプリの全機能をレビューする必要があるためです。
副業案件で多いケース:
- クライアントが「本番ユーザーのアカウントを審査官に渡したくない」と渋る
- Firebase AuthやCognito等でのサインアップが完了していない状態で申請を急ぐ
対策:
test@example.com/TestPass1234!のようなデモアカウントを事前にクライアントと合意して作成- SNSログインのみのアプリの場合は「App Store専用のメール+パスワード認証フロー」も追加するか、Appleへ「ソーシャルログインのみ」である旨をメモ欄に記載
4位|In-App Purchase(IAP)を実装しているのにApple経由で決済していない
クライアントからの要件で「月額課金をStripeで実装してほしい」という依頼は副業案件でも珍しくありません。しかしAppleのガイドライン(3.1.1)は、デジタルコンテンツや機能のアンロックにはIAPを使うことを義務付けています。
React Nativeのあるあるミス:
react-native-purchases(RevenueCat)の導入を先送りにしてStripeだけ実装- Webview内でStripe決済UIを表示してiOS版でも同じコードを流用
対策:
- 課金機能がある場合は見積もり段階でクライアントに「IAP実装が必要」を説明し費用に含める
react-native-purchases(RevenueCat)はドキュメントが充実しており、実装コストは初回でも1〜2日程度
5位|バイナリが古いiOS SDKまたはAPIでビルドされている
Appleは毎年秋に「〇〇月以降は最新Xcodeで作成したバイナリのみ受け付ける」という期限を設けます。副業案件では半年以上前に作られたExpoプロジェクトやRNプロジェクトをそのままビルドして申請することが多く、Xcodeのバージョン要件に引っかかるケースがあります。
またiOS 17以降で問題になっている例:
UIWebViewを使っているサードパーティライブラリが残っている(WKWebViewへの移行必須)- プッシュ通知にUNUserNotificationFrameworkを使わず古いAPIを使用
確認コマンド(EAS Build使用時):
# 最新のXcodeイメージを使ってビルドされているか確認
eas build:list --platform ios
# eas.jsonのXcodeバージョンを明示的に指定する例
# eas.json
{
"build": {
"production": {
"ios": {
"image": "latest"
}
}
}
}
提出前に使える!App Store審査リジェクト防止チェックリスト
| # | チェック項目 | 確認方法 |
|---|---|---|
| 1 | プライバシーポリシーURLがシークレットモードで開ける | ブラウザで確認 |
| 2 | NSUsageDescription系が全て「具体的な理由」で書かれている | Info.plist / app.json 目視 |
| 3 | デモアカウントをApp Store Connectのメモ欄に記載した | App Store Connect確認 |
| 4 | デジタルコンテンツ課金はIAP経由になっている | 課金フロー動作確認 |
| 5 | 最新Xcode対応バイナリでビルドしている | EASビルドログ確認 |
| 6 | UIWebViewを使っているパッケージがない | grep -r "UIWebView" ios/ |
| 7 | App Store用スクリーンショットが全サイズ揃っている | App Store Connect確認 |
| 8 | アプリが誤動作なくiPhone実機で動作する | TestFlightで確認 |
| 9 | サポートURL(問い合わせ先)が有効なURLになっている | App Store Connect確認 |
| 10 | 年齢レーティングがコンテンツに合っている | App Store Connectの「年齢制限」 |
副業受注時にクライアントと合意すべき3つの事項
審査に落ちる原因は技術的なミスだけではなく、要件定義の抜け漏れに起因することも多いです。副業契約時に以下を明文化しておくと後々のトラブルを防げます。
-
審査リジェクト時の修正対応は追加費用対象か否か
初回申請はスコープ内、2回目以降は時間単価で請求、など事前に合意しておく -
In-App Purchaseが必要かどうかの確認
「将来的に課金機能追加するかも」という案件はIAP対応を見積もりに含める -
プライバシーポリシーページの作成・管理は誰がやるか
エンジニア側でページ作成まで対応するならその工数も見積もりに入れる
副業プラットフォームで案件を探す際にも、こうした細かい要件のすり合わせが重要です。{{A8:coconala}}
まとめ
React Native副業案件でのApp Storeリジェクトは、原因のパターンがほぼ決まっています。
- プライバシーポリシーの不備
- 権限説明文の曖昧さ
- デモアカウントの未記載
- IAPを使わない課金実装
- 古いSDKでのビルド
これら5つを提出前チェックリストで潰すだけで、リジェクト率は大幅に下がります。特に副業では審査リジェクトによる納期遅延がそのまま信頼低下につながるため、「申請1週間前には審査準備完了」を習慣にするのが長くよい評判で仕事を受け続けるコツです。
iOSアプリ開発の全体像をより深く理解したい方には、実践的な解説書も参考になります。