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-21上級

Rork で作ったアプリを本番配信するときに詰まる 6 つのポイント — 個人開発者の実装メモ

Rork で作ったアプリが手元で動いても、ストア配信直前で想定外につまずくことがあります。私が個人開発で実際に踏んだ6つの落とし穴と、それぞれの回避策を具体的にお話しします。

Rork515本番リリースアプリ配信ストア審査個人開発186

個人でアプリを作って12年になりますが、「開発中は動いていたのに、本番リリース直前で詰まる」経験はいまだに毎回あります。Rork のようにAIがコードを生成してくれる環境では、さらに独特の落とし穴があります。生成されたコードが一見正しそうに見えても、本番環境特有の条件で破綻するケースがあるからです。

ここでは私が Rork で作ったアプリをストア配信するたびに遭遇した6つの具体的な詰まりポイントと、それぞれの回避策を共有します。公式ドキュメントにはまず載っていない、実際に踏み抜いた経験から得た知見です。

ポイント1: プレビュー環境と本番環境でのAPIキーの扱い

Rork のプレビュー環境では EXPO_PUBLIC_ 付きの環境変数が便利に使えます。しかし、AdMobのユニットIDやStripeの公開鍵などを EXPO_PUBLIC_ で管理していると、本番ビルド時に値が差し替わっていないまま公開されることがあります。

私は過去にAdMobのテスト用IDをそのまま本番に配信してしまい、気づいたのは翌日の朝、「収益がゼロのまま」というGoogle Analyticsの警告を見たときでした。

対策: 本番ビルド前に、必ず以下を確認します。

# ビルド前のチェック
grep -rn "ca-app-pub-3940256099942544" src/  # AdMobテストID
grep -rn "pk_test_" src/                      # Stripeテスト鍵
grep -rn "localhost" src/                     # 開発サーバーURL

この3つのgrepで引っかかる文字列は、本番ビルドに絶対に含めてはいけません。CI パイプラインに組み込んで自動検出できるようにすると事故を防げます。

ポイント2: Permissionダイアログの文言がローカライズされていない

Rork が生成するコードは、iOS の Info.plist に相当する権限説明文を英語のまま置いていることがよくあります。日本のストアに配信する場合、審査で落ちることはありませんが、ユーザー体験としては致命的です。

さらに厄介なのは、iOS では権限説明文が空文字列や空白のみだとアプリクラッシュの原因になる点です。プレビュー環境では問題なくても、本番ビルドで発覚します。

対策: 以下のような設定を app.json で明示的に用意します。

{
  "expo": {
    "ios": {
      "infoPlist": {
        "NSCameraUsageDescription": "写真を撮影して作品を記録するために使用します",
        "NSPhotoLibraryUsageDescription": "作品の画像を選択するために使用します",
        "NSLocationWhenInUseUsageDescription": "近くのアートスポットをご案内するために使用します"
      }
    }
  }
}

説明文は必ず「なぜ必要か」をユーザー視点で書きます。「写真を使用します」ではなく「作品を記録するために」のように、目的と利益を明示します。Apple の審査ではこの表現の質がチェックされます。

ポイント3: スプラッシュ画面が数秒固まる問題

Rork のデフォルトのスプラッシュ画面設定のまま本番ビルドすると、アプリ起動から最初の画面表示までの間、スプラッシュが長く表示される問題に遭遇します。これは多くの場合、useFonts や画像プリロードが同期的に処理されていることが原因です。

私は最初、「Rork が遅いのかな」と勘違いしていましたが、実際は自分の書いたローディング処理が悪かったのでした。

対策: 起動時の非同期処理を並列化し、スプラッシュを SplashScreen.preventAutoHideAsync() で明示的に制御します。

import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState } from 'react';
 
SplashScreen.preventAutoHideAsync();
 
export default function App() {
  const [ready, setReady] = useState(false);
 
  useEffect(() => {
    async function prepare() {
      try {
        await Promise.all([
          loadFonts(),
          loadInitialData(),
          preloadImages(),
        ]);
      } finally {
        setReady(true);
        await SplashScreen.hideAsync();
      }
    }
    prepare();
  }, []);
 
  if (\!ready) return null;
  return <RootNavigator />;
}

複数の初期化処理を Promise.all で並列化するだけで、起動時間が半分以下になることもあります。

ポイント4: iOS の Safe Area と Android の戻るボタン

Rork が生成するレイアウトは、シミュレータでは美しく表示されても、実機の iPhone で上下のSafe Areaに食い込んだり、Android の戻るボタン処理が抜けていたりすることが頻繁にあります。

特に Android の戻るボタンは、Web 開発の感覚ではつい忘れがちです。モーダル画面を開いたまま戻るボタンを押すとアプリが終了してしまう、というバグは審査では通ってしまうのでユーザーから苦情が来るまで気づきません。

対策: Safe Area は SafeAreaView ではなく react-native-safe-area-contextuseSafeAreaInsets を使い、戻るボタンは画面ごとに BackHandler.addEventListener を明示的に実装します。

useEffect(() => {
  const sub = BackHandler.addEventListener('hardwareBackPress', () => {
    if (modalVisible) {
      setModalVisible(false);
      return true;
    }
    return false;
  });
  return () => sub.remove();
}, [modalVisible]);

面倒に感じますが、Android ユーザーの評価に直結する部分です。

ポイント5: AdMob の ATT(App Tracking Transparency)対応

iOS 14以降、AdMobを使うアプリは ATT のダイアログを適切に出さないと、広告の配信率が極端に下がります。Rorkが生成するコードにはATT対応が含まれていないことがあり、そのまま配信すると収益が想定の半分以下になることがあります。

私は最初に出したアプリで、AdMobのeCPMが公表値の1/3しかなく、2週間気づきませんでした。原因は ATT を一切出していなかったためです。

対策: expo-tracking-transparency を使い、初回起動時にATTダイアログを表示します。

import { requestTrackingPermissionsAsync } from 'expo-tracking-transparency';
 
async function initTracking() {
  const { status } = await requestTrackingPermissionsAsync();
  if (status === 'granted') {
    // パーソナライズド広告が配信される
  } else {
    // 非パーソナライズド広告の設定に切り替え
  }
}

そして app.jsoninfoPlistNSUserTrackingUsageDescription を追加することを忘れないでください。この設定がないと ATT ダイアログ自体が出ません。

ポイント6: ストア審査で「Guideline 4.3 Spam」として落ちる

これは Rork 特有ではなく個人開発全般の話ですが、AIで生成されたアプリは「似たようなアプリが世の中に既に存在する」と判定されやすく、Apple の審査で Guideline 4.3(Spam)として落とされるケースが増えています。

対策: 私は以下の3点を必ず実装するようにしています。

  • アプリ独自の機能を最低1つ、他にはない形で実装する
  • スクリーンショットに「このアプリでしか得られない体験」が一目で分かる要素を入れる
  • App Store の説明文に、作者の独自の視点や作成意図を3行以上書く

テンプレートから生成しただけのアプリは、審査員に即座に見抜かれます。AIで高速に作ることと、独自性を持たせることは両立しなければいけません。

リリース後に備える設計

最後に、リリース「後」の話を少しだけ。アプリが公開されたら、必ず以下の仕組みを事前に入れておきます。

クラッシュレポートの自動収集

Sentry などを使ってクラッシュを自動収集する仕組みを入れます。ユーザーはアプリが落ちても報告してくれません。エラーログなしで原因を探すのは不可能に近いです。

緊急メンテナンス告知の仕組み

アプリ内に Firebase Remote Config などを使った「お知らせバナー」を仕込んでおき、緊急時にサーバーからアプリに通知できるようにします。バグが発覚してから審査を通してアップデートを配信するまでには最短でも1日かかります。その間、ユーザーに状況を伝える手段は絶対に必要です。

最新バージョン強制アップデートの仕組み

特にStripe課金やAPIキーを使っているアプリは、古いバージョンを使い続けられると運用上の問題が発生します。バージョン番号をサーバーで管理し、一定以下のバージョンではアプリを起動時にアップデート画面を出す、という設計を最初から入れておきます。

次にやってみてほしいこと

もしあなたが今、Rork で作ったアプリをリリース直前の段階で持っているなら、この記事を閉じる前に1つだけ試してほしいことがあります。プロジェクトのルートで grep -rn "ca-app-pub-3940256099942544\|pk_test_\|localhost" src/ を実行してみてください。何も出なければ、この記事のポイント1はクリアです。何かが出たら、本番配信前に必ず差し替えてください。

AIがコードを書いてくれる時代になっても、本番にアプリを出す責任は開発者にあります。その責任を負うための小さなチェックリストを、自分の中に1つずつ増やしていきましょう。

シェア

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

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

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

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

関連記事

開発ツール2026-07-10
クラッシュとして記録されない強制終了 — Rork アプリの JetsamEvent を読む
Crashlytics には何も出ていないのにレビューで「勝手に閉じる」と書かれる。その多くはメモリ超過による OS からの強制終了です。JetsamEvent レポートの読み方と、画像中心アプリのメモリ上限を実測から設計する手順をまとめます。
開発ツール2026-07-04
「続きを読む」を出すべきか、テキストの実測で決める — Rork(Expo)の折りたたみ表示設計
商品説明やレビュー本文を3行で畳み「続きを読む」を出す実装で、短い文にまでトグルが付いてしまう問題を解決します。onTextLayout で実際の行数を測り、はみ出す時だけトグルを出す設計を、iOS と Android の差、展開アニメーション、文字サイズ拡大への配慮まで動くコードでまとめます。
開発ツール2026-06-30
Rork アプリにホーム画面長押しのクイックアクションを足す — 動的項目とコールド起動の取りこぼしを防ぐ
アイコン長押しで出るクイックアクションを Rork(Expo)アプリに実装する設計です。静的・動的項目の使い分け、iOS と Android の差、そしてコールド起動でアクションがルーター準備前に届いて取りこぼす問題を、保留と再生で防ぐ実装手順までまとめます。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →