From 8165ec5baec56b34656ee12ee5a59b6bd91d7b2a Mon Sep 17 00:00:00 2001 From: Mariano Belinky Date: Mon, 16 Feb 2026 17:04:49 +0100 Subject: [PATCH] ios: fix gateway stability port blockers --- CHANGELOG.md | 1 + apps/ios/Sources/Settings/SettingsTab.swift | 3 +- .../GatewayConnectionControllerTests.swift | 34 ++++++++++++------- 3 files changed, 23 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8cb8a430d..9463ad96dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ Docs: https://docs.openclaw.ai - CLI/QR: restore fail-fast validation for `openclaw qr --remote` when neither `gateway.remote.url` nor tailscale `serve`/`funnel` is configured, preventing unusable remote pairing QR flows. (#18166) Thanks @mbelinky. - OpenClawKit/iOS ChatUI: accept canonical session-key completion events for local pending runs and preserve message IDs across history refreshes, preventing stuck "thinking" state and message flicker after gateway replies. (#18165) Thanks @mbelinky. - iOS/Talk: harden mobile talk config handling by ignoring redacted/env-placeholder API keys, support secure local keychain override, improve accessibility motion/contrast behavior in status UI, and tighten ATS to local-network allowance. (#18163) Thanks @mbelinky. +- iOS/Gateway: stabilize connect/discovery state handling, add onboarding reset recovery in Settings, and fix iOS gateway-controller coverage for command-surface and last-connection persistence behavior. (#18164) Thanks @mbelinky. ## 2026.2.15 diff --git a/apps/ios/Sources/Settings/SettingsTab.swift b/apps/ios/Sources/Settings/SettingsTab.swift index 47de97cc01..0f8e461d7d 100644 --- a/apps/ios/Sources/Settings/SettingsTab.swift +++ b/apps/ios/Sources/Settings/SettingsTab.swift @@ -548,7 +548,7 @@ struct SettingsTab: View { let err = await self.gatewayController.connectWithDiagnostics(gateway) if let err { - self.connectStatus.text = err + self.setupStatusText = err } } @@ -909,7 +909,6 @@ struct SettingsTab: View { // Reset onboarding state + clear saved gateway connection (the two things RootCanvas checks). GatewaySettingsStore.clearLastGatewayConnection() - OnboardingStateStore.markIncomplete() // RootCanvas also short-circuits onboarding when these are true. self.onboardingComplete = false diff --git a/apps/ios/Tests/GatewayConnectionControllerTests.swift b/apps/ios/Tests/GatewayConnectionControllerTests.swift index 609721784d..6c2046f081 100644 --- a/apps/ios/Tests/GatewayConnectionControllerTests.swift +++ b/apps/ios/Tests/GatewayConnectionControllerTests.swift @@ -96,25 +96,33 @@ private func withUserDefaults(_ updates: [String: Any?], _ body: () throws -> } @Test @MainActor func loadLastConnectionReadsSavedValues() { - withUserDefaults([ - "gateway.lastHost": "gateway.example.com", - "gateway.lastPort": 443, - "gateway.lastTls": true, - ]) { - let loaded = GatewayConnectionController.loadLastConnection(defaults: .standard) - #expect(loaded?.host == "gateway.example.com") - #expect(loaded?.port == 443) - #expect(loaded?.useTLS == true) + withUserDefaults([:]) { + GatewaySettingsStore.saveLastGatewayConnectionManual( + host: "gateway.example.com", + port: 443, + useTLS: true, + stableID: "manual:gateway.example.com:443") + let loaded = GatewaySettingsStore.loadLastGatewayConnection() + guard case let .manual(host, port, useTLS, stableID) = loaded else { + Issue.record("Expected manual last-gateway connection") + return + } + #expect(host == "gateway.example.com") + #expect(port == 443) + #expect(useTLS == true) + #expect(stableID == "manual:gateway.example.com:443") } } @Test @MainActor func loadLastConnectionReturnsNilForInvalidData() { withUserDefaults([ - "gateway.lastHost": "", - "gateway.lastPort": 0, - "gateway.lastTls": false, + "gateway.last.kind": "manual", + "gateway.last.host": "", + "gateway.last.port": 0, + "gateway.last.tls": false, + "gateway.last.stableID": "manual:bad:0", ]) { - let loaded = GatewayConnectionController.loadLastConnection(defaults: .standard) + let loaded = GatewaySettingsStore.loadLastGatewayConnection() #expect(loaded == nil) } }