RORK LABEN
FUNDING — Rorkの$15MシードはLeft Lane Capital主導で、Peak XV・True Ventures・Goodwater・a16z Speedrunが参加していますGROWTH — Rorkは月間74.3万訪問・成長率85%と、利用の伸びが続いていますMAX — Rork MaxはネイティブSwiftアプリを生成し、iPhone・iPad・Watch・TV・Vision Pro・iMessageに対応しますMAX — HealthKit・Core ML・Dynamic Islandなど、React Nativeでは届きにくい領域に踏み込めますMARKET — AppleもXcode 27でエージェント型コーディングを推進し、AIがネイティブ開発を担う流れが加速していますMARKET — Gartnerは2026年末までに新規アプリの75%が低コード/ノーコード製になると予測していますFUNDING — Rorkの$15MシードはLeft Lane Capital主導で、Peak XV・True Ventures・Goodwater・a16z Speedrunが参加していますGROWTH — Rorkは月間74.3万訪問・成長率85%と、利用の伸びが続いていますMAX — Rork MaxはネイティブSwiftアプリを生成し、iPhone・iPad・Watch・TV・Vision Pro・iMessageに対応しますMAX — HealthKit・Core ML・Dynamic Islandなど、React Nativeでは届きにくい領域に踏み込めますMARKET — AppleもXcode 27でエージェント型コーディングを推進し、AIがネイティブ開発を担う流れが加速していますMARKET — Gartnerは2026年末までに新規アプリの75%が低コード/ノーコード製になると予測しています
記事一覧/アプリ開発
アプリ開発/2026-07-03中級

Rork Max アプリで通信の切断と復帰に強くする — NWPathMonitor によるオフライン検知と再送設計

Rork Max のネイティブ Swift アプリで、電波が切れても壊れない通信設計を NWPathMonitor で組み立てます。オフラインの検知、Low Data Mode やモバイル回線の判定、復帰時の自動再送キューまで、動く Swift コードで示します。

Rork Max209NWPathMonitorNetwork2オフライン対応3Swift36iOS97

プレミアム記事

メモアプリのベータ版を配っていた頃、「書いたはずのメモが消えた」という報告を数件いただいたことがあります。手元では再現しません。ログを追っていくと、共通していたのは地下鉄やエレベーターの中で保存操作をしていたことでした。通信が切れた状態で保存ボタンを押すと、リクエストは静かに失敗し、画面上は何事もなかったように閉じてしまう。ユーザーには「保存できた」ようにしか見えていませんでした。

私自身、この手のバグを一番やっかいだと感じています。クラッシュすれば気づけますが、静かに失われるデータは誰も気づかないまま信頼だけを削っていきます。個人開発では問い合わせの一件一件が貴重なシグナルなので、なおさら見過ごせません。

Rork Max のネイティブ Swift であれば、Apple の Network フレームワークにある NWPathMonitor で通信経路の状態をリアルタイムに監視できます。ここからは、その監視をアプリ全体で共有できる形にまとめ、オフラインの明示・回線種別に応じた挙動の出し分け・復帰時の自動再送までを、実際に動くコードで組み立てていきます。私が2014年から個人開発でアプリを出し続けてきたなかでも、この静かな失敗への対処は繰り返し立ち返るテーマでした。

なぜ「サーバーに ping して確認」ではいけないのか

オフライン判定というと、起動時にサーバーへ軽いリクエストを投げて成否を見る、という方法を思いつく方は多いと思います。私も最初はそうしました。ですが、この方法は二重の意味で筋が良くありません。

ひとつは、ping が成功した「次の瞬間」に電波が切れる可能性を捉えられないこと。通信状態は連続的に変わるので、点で確認しても意味が薄いのです。

もうひとつは、Apple 自身が到達性の事前確認を推奨していないことです。NWPathMonitor のドキュメントでも、接続の可否は実際に接続を試みて判断し、経路の変化はモニターで観測するという設計が示されています。事前に「行けるかどうか」を判定してから送るのではなく、送る経路がいま存在するかを監視し続け、無いなら待つ、戻ったら流す、という姿勢に切り替えるのが本筋でした。

NWPathMonitor は Wi-Fi・モバイル回線・有線などのインターフェイスをまたいで、いま利用可能な経路の状態を通知してくれます。しかも「つながっているか」だけでなく、「その回線が高コスト(モバイルなど)か」「制約下(Low Data Mode など)か」までを教えてくれます。

NWPathMonitor を監視クラスにまとめる

まずは監視を一箇所に集約します。画面ごとに NWPathMonitor を生成すると、状態がばらつき、更新の取りこぼしも起きます。アプリで一つだけ持ち、SwiftUI から購読できる ObservableObject にするのが扱いやすい形です。

import Foundation
import Network
import Combine
 
@MainActor
final class NetworkMonitor: ObservableObject {
    static let shared = NetworkMonitor()
 
    @Published private(set) var isConnected = true
    @Published private(set) var isExpensive = false      // モバイル回線・テザリングなど
    @Published private(set) var isConstrained = false     // Low Data Mode など
    @Published private(set) var pathStatus: NWPath.Status = .satisfied
 
    private let monitor = NWPathMonitor()
    private let queue = DispatchQueue(label: "NetworkMonitor")
 
    private init() {
        monitor.pathUpdateHandler = { [weak self] path in
            // pathUpdateHandler はバックグラウンドキューで呼ばれる
            Task { @MainActor in
                self?.apply(path)
            }
        }
        monitor.start(queue: queue)
    }
 
    private func apply(_ path: NWPath) {
        pathStatus = path.status
        isConnected = path.status == .satisfied
        isExpensive = path.isExpensive
        isConstrained = path.isConstrained
    }
 
    deinit {
        monitor.cancel()
    }
}

ポイントは二つあります。pathUpdateHandlerstart(queue:) で渡した専用キュー、つまりバックグラウンドで呼ばれます。ここで直接 @Published を触ると UI 更新がメインスレッド外になり、警告やちらつきの原因になります。Task { @MainActor in } でメインへ渡してから反映しているのはそのためです。

もう一つは、monitor.start は必ず一度だけ呼ぶこと。ObservableObjectshared の単一インスタンスにしているのは、多重起動を防ぐ意味もあります。

Rork Max のプロンプトで土台を作る場合は、次のように依頼すると近い骨格が返ってきます。

Network フレームワークの NWPathMonitor を使い、
isConnected / isExpensive / isConstrained を @Published で公開する
@MainActor な ObservableObject を作ってください。
pathUpdateHandler の結果は MainActor に渡してから反映してください。

生成されたコードは、pathUpdateHandler がメインスレッドで @Published を触っていないか、start(queue:) を複数回呼んでいないかだけ確認すれば、たいていそのまま使えます。

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

この記事の続きを読む

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

この記事で得られること
NWPathMonitor を ObservableObject にまとめ、SwiftUI からオフライン状態を購読できる監視基盤を動くコードごと持ち帰れます
path.status だけでなく isExpensive・isConstrained を UX の判断に翻訳する具体的な指針が得られます
接続が戻った瞬間に失敗した送信を自動で流し直す再送キューの設計と、本番でつまずく箇所がわかります
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

アプリ開発2026-07-03
Rork Max アプリでダウンロードをアプリ終了後も続ける — バックグラウンド URLSession の設計と再起動復帰
Rork Max のネイティブ Swift アプリで、アプリがサスペンド・終了されてもダウンロードを OS 側で継続させるバックグラウンド URLSession の設計を解説します。再起動復帰・resumeData・isDiscretionary の実測挙動まで動くコードで示します。
アプリ開発2026-06-16
初回起動の前に壁紙パックを落としておく — Rork Max と Background Assets の使いどころ
コンテンツの多いアプリは、初回起動時に空のグリッドを見せてしまいがちです。アプリ本体とは別枠でコンテンツを先回りして落とす Background Assets を、Rork(Expo)では届かない領域として Rork Max のネイティブ Swift でどう実装するか、運用判断まで含めてまとめます。
アプリ開発2026-06-16
Rork Max で WeatherKit を使う天気アプリ — 認証とアトリビューションの落とし穴
Rork Max が生成したネイティブ Swift アプリに WeatherKit を組み込む際、最初に詰まるのは認証とアトリビューションでした。トークンの扱い、レート上限、必須の出典表示まで、実装で確認した手順を整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →