diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index 62f4a3d..b592fd2 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -320,11 +320,7 @@ final class RemoteStore: ObservableObject { func onAppear() { setupLiveActivityBridge() if demoMode { seedDemo(); return } - // Re-plan every connection the moment the network path changes (left Wi-Fi, joined a - // network, cellular⇄Wi-Fi) — the proactive half of "immediate switchover". - pathMonitor.onChange = { [weak self] in self?.handlePathChange() } - pathMonitor.start() - discovery.start() + startNetworkingIfNeeded() if isPaired { // Show the saved chat history immediately, before any host connects. if sessions.isEmpty { sessions = cachedSummaries } @@ -332,6 +328,22 @@ final class RemoteStore: ObservableObject { } } + /// Whether `startNetworkingIfNeeded` has already wired up path monitoring + LAN discovery. + private var networkingStarted = false + + /// Start the shared network-path monitor and LAN discovery once. Factored out of `onAppear` so + /// the background push handler — which runs when `onAppear` never fired (silent launch, no scene) + /// — can bring the same machinery up before it dials. + private func startNetworkingIfNeeded() { + guard !networkingStarted else { return } + networkingStarted = true + // Re-plan every connection the moment the network path changes (left Wi-Fi, joined a + // network, cellular⇄Wi-Fi) — the proactive half of "immediate switchover". + pathMonitor.onChange = { [weak self] in self?.handlePathChange() } + pathMonitor.start() + discovery.start() + } + /// A network-path change: tell each host connection to re-plan its transport now. private func handlePathChange() { guard !demoMode else { return }