RORK LABEN
BUILD — Rork Max はクラウド上の実機 Mac に Xcode と iOS SDK を載せ、SwiftUI を書き、ビルドし、エラーを読んで直す反復を回します。コードを吐いて終わりではない点が生成物の質に効いていますNATIVE — 生成されるのは React Native ではなく純粋な Swift / SwiftUI です。AR や Metal、ウィジェットなど React Native からは届かない機能に手が届くことが、他ビルダーとの実質的な差になりますPLATFORMS — 対応は iPhone・iPad・Apple Watch・Apple TV・Vision Pro に加えて iMessage まで含みます。ウォッチや拡張から入る設計を試すのに向いていますCOMPANION — Rork Companion により、有料の Apple Developer アカウントなしで生成したアプリを実機の iPhone で確認できます。最初の一本を試す段階の障壁が一段下がりましたPRICING — 無料で開始でき有料プランは月額25ドルから、Rork Max は月額200ドルの Max プランです。回収できる本数と規模を先に見積もっておく価値がありますDEADLINE — Google Play は2026年8月31日以降、新規アプリと更新の双方に対象 API レベル36 以上を要求します。残り10日で、生成物の targetSdkVersion は自分で確認が必要ですBUILD — Rork Max はクラウド上の実機 Mac に Xcode と iOS SDK を載せ、SwiftUI を書き、ビルドし、エラーを読んで直す反復を回します。コードを吐いて終わりではない点が生成物の質に効いていますNATIVE — 生成されるのは React Native ではなく純粋な Swift / SwiftUI です。AR や Metal、ウィジェットなど React Native からは届かない機能に手が届くことが、他ビルダーとの実質的な差になりますPLATFORMS — 対応は iPhone・iPad・Apple Watch・Apple TV・Vision Pro に加えて iMessage まで含みます。ウォッチや拡張から入る設計を試すのに向いていますCOMPANION — Rork Companion により、有料の Apple Developer アカウントなしで生成したアプリを実機の iPhone で確認できます。最初の一本を試す段階の障壁が一段下がりましたPRICING — 無料で開始でき有料プランは月額25ドルから、Rork Max は月額200ドルの Max プランです。回収できる本数と規模を先に見積もっておく価値がありますDEADLINE — Google Play は2026年8月31日以降、新規アプリと更新の双方に対象 API レベル36 以上を要求します。残り10日で、生成物の targetSdkVersion は自分で確認が必要です
記事一覧/開発ツール
開発ツール/2026-06-22上級

壊れたキャッシュで毎回起動時に落ちるアプリ——ユーザーが自力で抜け出せる「セーフモード起動」を設計する

永続化したキャッシュが壊れて起動のたびに同じ場所で落ちると、ユーザーには再インストールしか残りません。アプリ自身が早期クラッシュの連続を数え、対話可能になって初めて起動を確定し、危険な状態だけを段階的にリセットするセーフモードを、Expo(React Native)の実装で設計します。

Rork539Expo175React Native227クラッシュ対策4MMKV6設計10

プレミアム記事

個人開発で複数のアプリを運用していると、ごくたまに「特定の端末だけ、起動した瞬間に落ちて二度と開けない」という報告が届きます。私自身、永続化していた設定の一部が壊れたレコードになり、起動時の復元処理がそこで例外を投げて、以後は何度開いても同じ場所で落ち続ける状態に遭遇したことがあります。

厄介なのは、この状態に陥ったユーザーには手段がほとんど残らないことです。アプリは開けない、設定画面にもたどり着けない、つまりアンインストールして入れ直す以外にできることがありません。起動ループはそのまま離脱率に直結します。そして再インストールは、レビュー欄でいちばん辛辣な一言につながります。

ここで扱いたいのは、壊れた状態を後から手で直すことではありません。アプリ自身が「自分は起動のたびに早期に落ちている」と気づき、危険な状態だけを段階的に捨てて立ち上がり直す——そんなセーフモード起動の設計を扱います。

なぜ ErrorBoundary や Crashlytics では抜け出せないのか

まず、既存の備えがこの問題のどこに効かないかを整理しておきます。

ErrorBoundary は強力ですが、守れるのは React のレンダーツリーの内側だけです。起動ループの多くは、プロバイダが永続ストアを復元している最中や、ネイティブ側のモジュール初期化で起きます。ツリーがマウントされる前に落ちれば、境界は捕まえる対象を持ちません。React の例外捕捉の基本は未処理の Promise まで取りこぼさない ErrorBoundary の設計で扱っていますが、それでも「マウント前のクラッシュ」は守備範囲の外です。

Crashlytics はクラッシュを記録してくれますが、記録は事後です。ユーザーの端末でループが止まるわけではありません。iOS の 0x8badf00d ウォッチドッグ終了のように OS がメインスレッドの停滞で殺してくるケースとも違い、ここで問題なのは「コードは正しく動いているのに、与えられた永続データが壊れている」点です。コードを直しても、すでに壊れた状態を持っている端末は救われません。

つまり必要なのは、観測でも捕捉でもなく、端末側で自走する回復ロジックです。起動直後の白画面・クラッシュの切り分けを一歩進め、切り分けをアプリ自身にやらせる、と考えると分かりやすいかもしれません。

設計の核:起動を「未確認」で数え、対話可能になって初めて確定する

仕組みの中心はとても単純です。

起動が始まった瞬間に「未確認の起動」を1つ増やします。そしてアプリが実際に対話可能な状態(最初の画面が描画され、ユーザーが触れる状態)まで到達したら、その未確認カウントをゼロに戻します。これを「起動の確定」と呼ぶことにします。

もしアプリが対話可能になる前に落ちれば、確定は実行されません。未確認カウントは増えたまま残ります。次の起動でまた増え、また落ちれば、カウントは積み上がっていきます。これが連続して一定回数に達したとき、「この端末は起動ループに入っている」と判断します。

import { MMKV } from 'react-native-mmkv'
 
const store = new MMKV({ id: 'boot-guard' })
const KEY_PENDING = 'boot.pending'      // 未確認の連続起動回数
const KEY_LAST = 'boot.lastStartAt'     // 直近の起動開始時刻
const FAILED_BOOT_THRESHOLD = 3         // この回数の連続失敗でセーフモード
const RECENT_WINDOW_MS = 30_000         // この間隔を超える起動は「連続」とみなさない
 
export type BootDecision = { safeMode: boolean; failedBoots: number }
 
// プロバイダを一切マウントする前に、エントリの先頭で呼ぶ
export function beginBoot(): BootDecision {
  const now = Date.now()
  const lastStart = store.getNumber(KEY_LAST) ?? 0
  let pending = store.getNumber(KEY_PENDING) ?? 0
 
  // 速い連続でなければ起動ループではない。数え直す
  if (now - lastStart > RECENT_WINDOW_MS) pending = 0
 
  store.set(KEY_PENDING, pending + 1)
  store.set(KEY_LAST, now)
 
  // この起動を始める前に、すでに閾値ぶん落ちているか
  return { safeMode: pending >= FAILED_BOOT_THRESHOLD, failedBoots: pending }
}
 
// 対話可能になったら呼ぶ。これで連続失敗カウントが消える
export function confirmBoot() {
  store.set(KEY_PENDING, 0)
}

RECENT_WINDOW_MS を挟んでいるのは、誤検知を避けるためです。ユーザーがアプリを開いてすぐ閉じ、数日後にまた開いた——というのはクラッシュループではありません。連続して短時間に起動が積み上がったときだけをループとみなします。

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

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
ErrorBoundary でも Crashlytics でも救えない「起動ループ」を、アプリ自身に気づかせて自己回復させる設計
起動を未確認で数え、対話可能になって初めて確定する仕組みと、なぜ同期ストレージ(MMKV)でないと数えられないのか
被害範囲を最小にする段階的リセットの梯子と、ユーザー作成データを絶対に触らないための原則
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

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

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

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

関連記事

開発ツール2026-05-07
Rork で作ったアプリの「原因不明クラッシュ」を撲滅する — Error Boundary と Unhandled Promise の実戦的な捕捉法
Rorkが生成したコードに多い、awaitのエラー握り潰しとErrorBoundary不在による原因不明クラッシュへの対策です。react-error-boundaryの配置、Unhandled Promise Rejectionの捕捉、SentryとCrashlyticsの選び方までを解説します。
開発ツール2026-08-04
名前が20文字ちょうどでも保存できない — 文字数の数え方を1か所に決めるまでの実測
絵文字や合成文字が入ると、クライアントとサーバーで文字数が食い違います。4つの数え方をNode v22で実測し、切り詰め2,000件の破損率75.6%・UTF-8往復での置換文字化36.1%という結果から、カウントの正本を1か所に置く設計へ至るまでをまとめました。
開発ツール2026-07-30
Renovate が触ってよい依存と、触ってはいけない依存 — Expo SDK 57 の123パッケージを機械的に切り分ける
Rork 生成アプリに依存の自動更新を入れると、Expo が版を管理している123パッケージまで巻き込まれます。2026年7月30日時点の実測では、うち6件が npm の最新版へメジャー更新される差でした。除外リストを手で書かず SDK から機械生成する手順をまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →