RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-04-26中級

TestFlight は問題ないのに App Store 公開後にクラッシュする4つの理由

TestFlightで完璧に動作したRorkアプリがApp Store公開後にクラッシュする理由は4つのパターンに絞られます。原因の特定方法と具体的な修正手順を解説します。

TestFlight10App Store78クラッシュ4トラブルシューティング77Sentry6環境変数4iOS108

TestFlight で何十回もテストして「完璧だ」と確信してから App Store に公開した途端、クラッシュレポートが届く——これは Rork で iOS アプリを初めて公開した開発者の多くが通る洗礼です。

「TestFlight と App Store の違いは審査があるかどうかだけでしょう?」と思われる方もいるかもしれませんが、実は実行環境そのものにいくつかの重要な差異があります。その差異が本番クラッシュの原因になります。よく遭遇するパターンを4つに絞って、原因と修正手順を具体的にお伝えします。

なぜ TestFlight と App Store で挙動が変わるのか

本題に入る前に、理解しておくと後が楽になる前提知識があります。

TestFlight は 開発用・AdHoc 配布ビルド を配布する仕組みです。一方、App Store は 本番用(Distribution)証明書でビルドされたアーカイブが使われます。この証明書の違いに付随して、アプリが参照する設定ファイル、API キー、フラグ、ネットワーク設定などが変わる可能性があります。

また、TestFlight は「あなたやテスターが使っているデバイス」で動いていますが、App Store では数年前のモデル(iPhone 8 相当)や、OS バージョンが古い環境でも使われます。この2点を念頭に置いて、以下を読み進めてください。

パターン①:本番ビルドで環境変数が undefined になる

Rork で API を使うアプリを開発するとき、process.env.EXPO_PUBLIC_API_KEY のような環境変数を使うことがあります。TestFlight テスト中は .env ファイルや EAS の preview プロファイル設定で動いていても、App Store 向けの production プロファイルで別の環境変数を参照していた場合に、本番環境で変数が undefined になりクラッシュします。

確認すべき箇所

// eas.json — preview にしか env がないとproductionで undefined になる
{
  "build": {
    "preview": {
      "distribution": "internal",
      "env": {
        "EXPO_PUBLIC_API_KEY": "test-key-here"
      }
    },
    "production": {
      "distribution": "store"
      // ← env の定義がない!
    }
  }
}

修正手順

  1. Expo ダッシュボード(expo.dev)→ プロジェクト → Secrets を開く
  2. EXPO_PUBLIC_API_KEY を Environment: Production のシークレットとして追加
  3. eas.jsonproduction.env で参照するよう修正する
"production": {
  "distribution": "store",
  "env": {
    "EXPO_PUBLIC_API_KEY": "$EXPO_PUBLIC_API_KEY"
  }
}
  1. eas build --platform ios --profile production で再ビルドして動作確認

環境変数の設定ミスについては環境変数・設定ファイルのエラー対処ガイドも合わせて確認してください。

パターン②:App Transport Security(ATS)が本番で厳格に適用される

iOS には App Transport Security(ATS)という仕組みがあり、HTTP(非暗号化)通信をデフォルトでブロックします。TestFlight のデバッグビルドでは ATS の例外設定が緩くなっていても、本番ビルドでは厳格な ATS が適用されて通信が失敗するケースがあります。

症状で見分ける

  • ネットワーク系のエラー(NSURLErrorDomainSSL 関連)が Console に出る
  • 外部 API の呼び出しが全て失敗する
  • アセットや画像の URL が http:// で始まっている

app.json での確認と修正

{
  "ios": {
    "infoPlist": {
      "NSAppTransportSecurity": {
        "NSAllowsArbitraryLoads": false,
        "NSExceptionDomains": {
          "your-api.example.com": {
            "NSExceptionAllowsInsecureHTTPLoads": false,
            "NSExceptionMinimumTLSVersion": "TLSv1.2"
          }
        }
      }
    }
  }
}

NSAllowsArbitraryLoads: true にすると審査で指摘を受ける可能性があるため、必要なドメインだけを例外設定するのが正しいやり方です。接続先 API サーバーが HTTPS に対応しているかどうかも再確認してください。

パターン③:プライバシーマニフェストの申告漏れ

2024年以降、Apple は Privacy Manifest(PrivacyInfo.xcprivacy)Required Reason APIs の申告を必須化しました。TestFlight 配布では見逃されても、App Store の審査プロセスで「申告されていない API を使用している」として警告が届き、アプリが正常に動作しないケースがあります。

Rork で生成されたアプリが内部的に利用する可能性のある Required Reason APIs には以下のものがあります。

  • UserDefaults(AsyncStorage 経由で内部利用)
  • Disk space APIs(NSFileManager 経由)
  • File timestamp APIs

Expo での対応

Expo SDK 50 以降では多くのマニフェスト設定が自動生成されますが、カスタムネイティブモジュールを使っている場合は手動対応が必要です。

{
  "ios": {
    "privacyManifests": {
      "NSPrivacyAccessedAPITypes": [
        {
          "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
          "NSPrivacyAccessedAPITypeReasons": ["CA92.1"]
        },
        {
          "NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryDiskSpace",
          "NSPrivacyAccessedAPITypeReasons": ["E174.1"]
        }
      ]
    }
  }
}

詳細な対応手順はプライバシーマニフェスト・Required Reason API 申告の修正ガイドを参照してください。

パターン④:低スペック端末でのメモリ不足クラッシュ

「iPhone 15 Pro Max で完璧に動いたから大丈夫」——この考え方が最も危険です。App Store では iPhone 8(2017年・RAM 2GB)のような端末でも動作することが期待されています。

AI 機能や画像処理を多用する Rork アプリでは、メモリ消費量が想定より大きくなりがちです。高スペック端末のテストでは問題なかったものが、メモリの少ない端末で OOM(Out of Memory)クラッシュを起こすことがあります。

対策:リスト表示の最適化

// FlatList の render 件数を制限してメモリを節約する
<FlatList
  data={items}
  renderItem={renderItem}
  maxToRenderPerBatch={10}   // 一度にレンダリングするアイテム数(デフォルト: 10)
  windowSize={5}             // 画面外を保持するウィンドウ数(デフォルト: 21)
  removeClippedSubviews={true} // 非表示アイテムをアンマウントしてメモリを解放
  initialNumToRender={8}     // 初期レンダリング件数
/>

対策:画像の適切なサイズ管理

import { Image } from 'expo-image'; // expo-image はキャッシュ管理が優秀
 
<Image
  source={{ uri: imageUrl }}
  style={{ width: 300, height: 300 }}
  contentFit="cover"
  // サムネイルには縮小URLを使い、フルサイズをメモリに展開しない
  transition={200}
/>

Rork のプロンプトに「メモリ効率を考慮した実装にしてください」「大きな画像は expo-image を使ってください」と明示すると、生成コードの質が上がることがあります。アプリ全体のパフォーマンス改善についてはパフォーマンス最適化ガイドも参考にしてください。

本番クラッシュを素早く把握するために Sentry を導入する

上記4パターンを確認してもクラッシュが再現しない場合、本番クラッシュのログを自分で確認できる環境を整える点が肝心です。

Sentry は Rork アプリへの導入が比較的シンプルで、クラッシュの発生箇所・スタックトレース・デバイス情報を自動収集してくれます。

npx expo install @sentry/react-native
// app/_layout.tsx または App.tsx の最初に追加
import * as Sentry from "@sentry/react-native";
 
Sentry.init({
  dsn: "https://your-dsn@sentry.io/project-id",
  release: "com.yourcompany.yourapp@1.0.0",
  dist: "1",
  enabled: !__DEV__, // 本番環境のみ有効化
  tracesSampleRate: 0.1,
});
 
export default Sentry.wrap(RootLayout);

Sentry を入れておくと、次のリリース以降は「クラッシュがどのデバイス・どのコードで起きているか」が即座にわかります。設定の詳細はSentry クラッシュ監視のセットアップガイドをご覧ください。

App Store 公開前のチェックリスト

最後に、本番クラッシュを防ぐための確認項目をまとめます。

  • eas.jsonproduction プロファイルに全ての環境変数が定義されているか
  • API 接続先が全て HTTPS に対応しているか
  • NSAllowsArbitraryLoadsfalse のまま本番ビルドが通るか
  • Required Reason APIs が Privacy Manifest に全て申告されているか
  • iPhone SE(第2世代以降)や iPhone 8 相当の端末で動作確認したか
  • FlatList や画像コンポーネントのメモリ使用量が適切か
  • Sentry または同等のクラッシュ監視ツールが本番環境に設定されているか

TestFlight では完璧に動いたのに本番でクラッシュする経験は、開発者なら誰でも一度は通る道です。ただ、原因のパターンは限られているので、この4つを頭に入れておけば対処が格段に早くなります。次のリリースが少しでもスムーズにいくことを願っています。

シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-05-21
RorkでビルドしたiOSアプリがTestFlightで「ITMS-90683」拒否される — Info.plistの使用目的文字列の埋め方
Rork書き出しのiOSアプリをApp Store Connectに提出した直後、メールで「ITMS-90683: Missing Purpose String in Info.plist」を受け取る現象について、原因とapp.jsonからの恒久的な修正手順を、12年間の個人開発で繰り返しハマってきた立場から具体的に説明します。
開発ツール2026-05-08
Rork Max の Cloud Compile が失敗する原因と、すぐに試せる対処法
Rork Max の Cloud Compile でビルドが失敗する時の原因を症状別に整理し、コード署名エラー・Swift バージョン不一致・タイムアウトなど、よくあるケースへの対処法を解説します。
開発ツール2026-04-16
シミュレーターで動くのに実機でクラッシュ — Rork Max アプリの原因特定と修正ガイド
Rork Max で生成した SwiftUI アプリがシミュレーターでは正常動作するのに実機でクラッシュする問題を5つのパターン別に解説。クラッシュログの読み方から具体的な修正方法まで紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →