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

従量制回線と低データモードを尊重して先読みを止める通信設計

画像中心の Rork(Expo)アプリで、従量制回線や低データモードのときに先読みを抑える通信設計を扱います。NetInfo の details から回線の性質を読み、画質を落とし、プリフェッチを遅延させる適応ロジックを実装コードとともに整理します。

Rork539Expo175NetInfo低データモードプリフェッチ通信最適化

プレミアム記事

私が運用している壁紙アプリのレビューに、あるとき「Wi-Fi のないところで開いたら、あっという間にギガが減った」という指摘が届きました。原因はすぐに分かりました。一覧画面で次のページの高解像度画像を片っ端から先読みしていたのです。Wi-Fi なら快適さに貢献する挙動が、従量制のモバイル回線では利用者の通信量を静かに食いつぶしていました。画像を多く扱うアプリほど、この「良かれと思った先読み」が逆効果になりやすいと感じています。

ここでは Rork で生成した Expo アプリを題材に、回線の性質を読み取って先読みと画質を適応的に切り替える通信設計を整理します。鍵になるのは、回線を「つながっているか/いないか」の二値で見るのをやめ、「従量制か」「低速か」「低データモードか」まで踏み込んで判断することです。

「オンラインか否か」だけで判断するのをやめる

多くのアプリは isConnected だけを見て、つながっていれば全部やる、という作りになっています。しかし利用者の回線は一様ではありません。NetInfo の details には、判断に使える情報がもっと含まれています。

判定軸取得元(NetInfo)意味するもの
従量制かどうかdetails.isConnectionExpensiveOS が「お金のかかる回線」と見なしている(テザリング等を含む)
回線種別type(wifi / cellular / ...)Wi-Fi かモバイルか
セルラー世代details.cellularGeneration(3g/4g/5g)速度の目安(3g なら重い先読みは避ける)
低データモード下記参照利用者が明示的に通信を絞っている

isConnectionExpensive は OS が判断した「従量制相当」のフラグで、テザリング経由の Wi-Fi なども含まれます。これを尊重するだけでも、レビューにあったような「ギガが溶ける」事故の多くは防げます。

低データモードについては補足が要ります。iOS の Low Data Mode / Android のデータセーバーは、アプリから直接「オンかどうか」を読む統一 API が乏しいのが実情です。実務では、isConnectionExpensive を低データモードの代理シグナルとして扱い、加えて「アプリ内に節約スイッチを用意して利用者自身に選ばせる」二段構えにするのが現実的です。OS の意思(従量制判定)とアプリの設定(明示スイッチ)を両方ポリシーに合流させます。

通信判定を一箇所に集約する

回線の判定を画面ごとに散らすと、必ず判断がばらつきます。回線情報を1つのポリシーに変換するレイヤーを作り、各画面はそのポリシーだけを見るようにします。

// net/networkPolicy.ts
import NetInfo, { NetInfoState } from "@react-native-community/netinfo";
 
export type PrefetchLevel = "full" | "lite" | "off";
export type ImageQuality = "high" | "medium" | "low";
 
export interface NetworkPolicy {
  prefetch: PrefetchLevel;   // 先読みの強さ
  imageQuality: ImageQuality; // 取得する画質
  allowAutoplay: boolean;     // 動画・GIF の自動再生可否
}
 
// 回線状態 + アプリの節約設定 を 1 つのポリシーへ変換する
export function derivePolicy(
  state: NetInfoState,
  saverEnabled: boolean
): NetworkPolicy {
  // つながっていない
  if (!state.isConnected) {
    return { prefetch: "off", imageQuality: "low", allowAutoplay: false };
  }
 
  const expensive = !!(state.details as any)?.isConnectionExpensive;
  const gen = (state.details as any)?.cellularGeneration as string | undefined;
  const isSlowCellular = state.type === "cellular" && (gen === "2g" || gen === "3g");
 
  // 利用者が節約を選んでいる、または OS が従量制と判断、または低速
  if (saverEnabled || expensive || isSlowCellular) {
    return { prefetch: "off", imageQuality: "medium", allowAutoplay: false };
  }
 
  // 通常のモバイル(4g/5g・非従量制)
  if (state.type === "cellular") {
    return { prefetch: "lite", imageQuality: "high", allowAutoplay: false };
  }
 
  // Wi-Fi(非従量制)— 全力で先読み
  return { prefetch: "full", imageQuality: "high", allowAutoplay: true };
}

このポリシーを React のコンテキストで配ると、各画面は useNetworkPolicy() を読むだけで一貫した判断ができます。

// net/NetworkPolicyProvider.tsx
import React, { createContext, useContext, useEffect, useState } from "react";
import NetInfo from "@react-native-community/netinfo";
import { derivePolicy, NetworkPolicy } from "./networkPolicy";
import { useDataSaver } from "../settings/useDataSaver"; // アプリ内の節約スイッチ
 
const Ctx = createContext<NetworkPolicy>({
  prefetch: "lite", imageQuality: "high", allowAutoplay: false,
});
 
export function NetworkPolicyProvider({ children }: { children: React.ReactNode }) {
  const saver = useDataSaver();
  const [policy, setPolicy] = useState<NetworkPolicy>(Ctx._currentValue);
 
  useEffect(() => {
    // 購読開始時に現在値を一度取得し、以後は変化を購読
    const unsub = NetInfo.addEventListener((state) => {
      setPolicy(derivePolicy(state, saver));
    });
    NetInfo.fetch().then((state) => setPolicy(derivePolicy(state, saver)));
    return () => unsub();
  }, [saver]);
 
  return <Ctx.Provider value={policy}>{children}</Ctx.Provider>;
}
 
export const useNetworkPolicy = () => useContext(Ctx);

ポイントは、節約スイッチ(saver)の変化も依存に入れることです。利用者が設定でスイッチを切り替えた瞬間にポリシーが再計算され、先読みの挙動が即座に追従します。

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

この記事の続きを読む

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

この記事で得られること
回線が従量制・低速・低データモードのとき、自動で先読みを止めて画質を落とす適応プリフェッチの実装を手に入れられる
NetInfo の details から isConnectionExpensive やセルラー世代を読み、ポリシーに変換する一元化された通信判定レイヤーを組み立てられる
全部先読みするか何もしないかの二択をやめ、回線に応じて段階的に振る舞いを変える設計に移行できる
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

アプリ開発2026-08-18
Rork のプロジェクトで targetSdkVersion 36 を通すまでに直した3か所
app.json に targetSdkVersion 36 と書いてあるのに、ビルドが読んでいた値は 35 でした。実効値を報告するスクリプトと、引き上げ・更新停止・延長申請の三択の分け方を残します。
アプリ開発2026-08-16
グラフが壊れて見えるのは、データが多いときではなく最初の数日でした
記録アプリの折れ線グラフが、データの少ない最初の数日だけ線が消える。原因はY軸の幅が0になり座標がNaNになることでした。実測した挙動と、描画前に置く小さな正規化層を紹介します。
アプリ開発2026-08-06
壁紙の上の文字が読めるかを、端末ではなく取り込み時に決める — 判定指標を4つ測り比べた記録
壁紙の上に置くステータスバーや見出しが読めるかを、端末での画像解析ではなく取り込み時のメタデータで決める設計です。240枚のコーパスで判定指標を4つ実測し、縮小画像での判定が何と一致するのかまで記録しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →