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

アプリスイッチャーに個人的な画面が残る——背景へ回した瞬間のスナップショットを隠す設計

Rork が生成した React Native アプリをホームに戻すと、iOS はその瞬間の画面をアプリスイッチャー用に撮影してディスクに保存します。手記や個人的な入力画面はそこに残り、第三者の目に触れます。iOS の目隠しオーバーレイ(inactive で出す理由)、Android の FLAG_SECURE、機密画面だけに絞る方法、スクショ検知までを動くコードで示します。

Rork539React Native227Expo175プライバシー10セキュリティ設計

プレミアム記事

ある朝、自分の手記アプリを開いたまま電話に出ようとして、ホームボタンを二度押ししました。アプリスイッチャーに並んだサムネイルの中に、さっきまで書いていた個人的な一文がそのまま写っていました。家族に画面を覗かれて困るような内容ではありませんでしたが、「これは本人以外の手に渡るのを前提にしていなかった画面だ」と気づいて、少し背筋が冷えました。

iOS はアプリをホームへ戻した瞬間、その時点の画面を撮影してアプリスイッチャーのプレビューに使います。この画像はメモリ上だけのものではなく、ディスクに保存されます。つまり、パスコードでロックする前のホーム画面に、あなたのアプリの中身がしばらく残り続けるということです。手記、引き寄せの記録、健康データ、決済直前の金額——本人だけが見る前提で作った画面ほど、ここに残ると困ります。

私自身、個人開発で手記系・引き寄せ系のアプリを複数運用していますが、この「背景に回した瞬間」の守りは、Rork が生成した React Native のコードにも、Rork Max が書き出した Swift にも、初期状態では入っていません。守りの入り口は、その瞬間に画面へ目隠しを差し込むことにあります。つまずきやすい順序の問題から順に組み立てていきます。

守るべきは「表示している間」ではなく「離れる瞬間」

セキュリティ対策というと、画面を表示している最中の話だと考えがちです。けれども今回守りたいのは、ユーザーがアプリから離れる遷移の一瞬です。iOS はアプリが前面から外れるとき、UI のスナップショットを撮ってアプリスイッチャーに使います。撮影されるのは「完全に背景へ落ちた後」ではなく、その手前の inactive 状態に入るタイミングです。

React Native の AppState は、この遷移を3つの値で表します。前面で動いている active、操作を受け付けない過渡状態の inactive(iOS のみ)、そして背景の background です。コントロールセンターを下ろした、電話がかかってきた、アプリスイッチャーを開いた——こうした場面ではまず inactive を通過します。

ここに最初の落とし穴があります。background になってから目隠しを出すと、スナップショットの撮影に間に合いません。撮影はすでに inactive の段階で済んでいるからです。守りの入り口は background ではなく inactive だ、という一点を最初に押さえておきます。

iOS:inactive で目隠しオーバーレイを出す

まず、アプリのルートに常駐する目隠し用のオーバーレイを用意します。active のときは透明(実質非表示)、それ以外のときは画面全体を覆う、という素直な作りです。状態管理は外部ライブラリを使わず、軽量な AppState 購読フックにまとめます。

// hooks/usePrivacyShield.ts
import { useEffect, useRef, useState } from "react";
import { AppState, AppStateStatus } from "react-native";
 
// active 以外(inactive / background)のときに true を返す。
// iOS のスナップショットは inactive で撮られるため、background を待ってはいけない。
export function usePrivacyShield(enabled: boolean) {
  const [shielded, setShielded] = useState(false);
  const appState = useRef<AppStateStatus>(AppState.currentState);
 
  useEffect(() => {
    if (!enabled) {
      setShielded(false);
      return;
    }
 
    const handle = (next: AppStateStatus) => {
      // active へ戻った瞬間だけ目隠しを外す。
      // それ以外の遷移(inactive / background)はすべて覆う側に倒す。
      setShielded(next !== "active");
      appState.current = next;
    };
 
    // 初期表示時の取りこぼし防止(起動直後が inactive のことがある)。
    setShielded(AppState.currentState !== "active");
 
    const sub = AppState.addEventListener("change", handle);
    return () => sub.remove();
  }, [enabled]);
 
  return shielded;
}

このフックをアプリ最上位の1か所で使い、覆う UI を被せます。画面ごとに置くと、遷移の瞬間に「今どの画面か」を判定する余裕がないため、必ずルートに置きます。

// components/PrivacyShield.tsx
import { View, StyleSheet, Image } from "react-native";
import { usePrivacyShield } from "../hooks/usePrivacyShield";
 
export function PrivacyShield({ enabled }: { enabled: boolean }) {
  const shielded = usePrivacyShield(enabled);
  if (!shielded) return null;
 
  // ブランドのロゴ1枚だけを中央に置く。中身は一切描かない。
  return (
    <View style={styles.cover} pointerEvents="none">
      <Image
        source={require("../assets/shield-logo.png")}
        style={{ width: 96, height: 96, opacity: 0.9 }}
        resizeMode="contain"
      />
    </View>
  );
}
 
const styles = StyleSheet.create({
  cover: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: "#0E1116",
    alignItems: "center",
    justifyContent: "center",
    zIndex: 9999,
  },
});

ルートではこう組み込みます。enabled には「いま機密画面にいるか」を渡せるようにしておくと、後で画面単位の制御に発展させられます。

// app/_layout.tsx(Expo Router の例)
import { Stack } from "expo-router";
import { PrivacyShield } from "../components/PrivacyShield";
 
export default function RootLayout() {
  return (
    <>
      <Stack />
      {/* まずはアプリ全体で常に有効化。後で画面単位に絞る */}
      <PrivacyShield enabled={true} />
    </>
  );
}

ここまでで、ホームに戻したりアプリスイッチャーを開いたりした瞬間、画面はロゴ1枚の目隠しに切り替わり、撮影されるスナップショットも目隠し後の状態になります。

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

この記事の続きを読む

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

この記事で得られること
個人的な入力画面がアプリスイッチャーに残っていた、という不安を抱えていた人が、背景遷移の瞬間に目隠しを差し込む実装を今日手に入れられる
なぜ background では遅れて inactive で出す必要があるのか、iOS と Android で守り方がまったく違う理由を理解し、片方だけ守って安心する事故を避けられる
アプリ全体ではなく機密画面だけに FLAG_SECURE を絞り、スクリーンショット検知でユーザーに知らせる本番運用パターンを実装できる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-07-30
Renovate が触ってよい依存と、触ってはいけない依存 — Expo SDK 57 の123パッケージを機械的に切り分ける
Rork 生成アプリに依存の自動更新を入れると、Expo が版を管理している123パッケージまで巻き込まれます。2026年7月30日時点の実測では、うち6件が npm の最新版へメジャー更新される差でした。除外リストを手で書かず SDK から機械生成する手順をまとめます。
開発ツール2026-07-28
prebuild --clean で消える手入れを、上げる前に数える — Expo SDK 57 移行の棚卸し
Expo SDK 57 への移行前に、ios/ へ加えた手入れが prebuild の再生成でいくつ失われるかを数える手順をまとめました。素の差分649行のうち意味を持つのは3行。ノイズを正規化して実質的な変更だけを抽出するスクリプトと、config plugin への移し替えを実測つきで共有します。
開発ツール2026-07-27
最低サポート iOS をいつ上げるか — 利用率ではなく、コードに残った分岐の数で決める
最低サポート OS の引き上げを利用率で判断すると、毎年同じ結論になって先送りが続きます。OS 分岐に注記を付けて棚卸しし、引き上げ先ごとに消せる分岐を数えるスクリプトと、引き上げ後に見る指標をまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →