diff --git a/apps/ios/LocalSigning.xcconfig.example b/apps/ios/LocalSigning.xcconfig.example index 22e976a77f8f..3c990f6af603 100644 --- a/apps/ios/LocalSigning.xcconfig.example +++ b/apps/ios/LocalSigning.xcconfig.example @@ -4,11 +4,11 @@ OPENCLAW_CODE_SIGN_STYLE = Automatic OPENCLAW_DEVELOPMENT_TEAM = YOUR_TEAM_ID -OPENCLAW_APP_BUNDLE_ID = ai.openclaw.client -OPENCLAW_SHARE_BUNDLE_ID = ai.openclaw.client.share -OPENCLAW_ACTIVITY_WIDGET_BUNDLE_ID = ai.openclaw.client.activitywidget -OPENCLAW_WATCH_APP_BUNDLE_ID = ai.openclaw.client.watchkitapp -OPENCLAW_WATCH_EXTENSION_BUNDLE_ID = ai.openclaw.client.watchkitapp.extension +OPENCLAW_APP_BUNDLE_ID = ai.openclawfoundation.app +OPENCLAW_SHARE_BUNDLE_ID = ai.openclawfoundation.app.share +OPENCLAW_ACTIVITY_WIDGET_BUNDLE_ID = ai.openclawfoundation.app.activitywidget +OPENCLAW_WATCH_APP_BUNDLE_ID = ai.openclawfoundation.app.watchkitapp +OPENCLAW_WATCH_EXTENSION_BUNDLE_ID = ai.openclawfoundation.app.watchkitapp.extension // Leave empty with automatic signing. OPENCLAW_APP_PROFILE = diff --git a/apps/ios/README.md b/apps/ios/README.md index 4d405e619687..0dddbc97f356 100644 --- a/apps/ios/README.md +++ b/apps/ios/README.md @@ -61,7 +61,7 @@ Prereqs: Release behavior: - Local development uses the canonical `ai.openclawfoundation.app*` bundle IDs when the OpenClaw team is available, and unique `ai.openclawfoundation.app.test.*` bundle IDs only for non-canonical fallback teams. -- Beta release uses canonical `ai.openclaw.client*` bundle IDs through a temporary generated xcconfig in `apps/ios/build/BetaRelease.xcconfig`. +- Beta release uses canonical `ai.openclawfoundation.app*` bundle IDs through a temporary generated xcconfig in `apps/ios/build/BetaRelease.xcconfig`. - Beta release also switches the app to `OpenClawPushTransport=relay`, `OpenClawPushDistribution=official`, and `OpenClawPushAPNsEnvironment=production`. - The beta flow does not modify `apps/ios/.local-signing.xcconfig` or `apps/ios/LocalSigning.xcconfig`. - `apps/ios/version.json` is the pinned iOS release version source. @@ -319,7 +319,7 @@ Automatic wake/reconnect hardening: 5. If network path is unclear: - switch to manual host/port + TLS in Gateway Advanced settings 6. In Xcode console, filter for subsystem/category signals: - - `ai.openclaw.ios` + - `ai.openclawfoundation.app` - `GatewayDiag` - `APNs registration failed` 7. Validate background expectations: diff --git a/apps/ios/Sources/Chat/IOSGatewayChatTransport.swift b/apps/ios/Sources/Chat/IOSGatewayChatTransport.swift index 2ef849f17a89..3fc0be111f1b 100644 --- a/apps/ios/Sources/Chat/IOSGatewayChatTransport.swift +++ b/apps/ios/Sources/Chat/IOSGatewayChatTransport.swift @@ -5,7 +5,7 @@ import OpenClawProtocol import OSLog struct IOSGatewayChatTransport: OpenClawChatTransport { - static let logger = Logger(subsystem: "ai.openclaw", category: "ios.chat.transport") + static let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "ios.chat.transport") static let defaultChatSendTimeoutMs = 30000 private let gateway: GatewayNodeSession diff --git a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift index 8f1b58b13484..689128e89553 100644 --- a/apps/ios/Sources/Gateway/GatewaySettingsStore.swift +++ b/apps/ios/Sources/Gateway/GatewaySettingsStore.swift @@ -2,9 +2,9 @@ import Foundation import os enum GatewaySettingsStore { - private static let gatewayService = "ai.openclaw.gateway" - private static let nodeService = "ai.openclaw.node" - private static let talkService = "ai.openclaw.talk" + private static let gatewayService = "ai.openclawfoundation.app.gateway" + private static let nodeService = "ai.openclawfoundation.app.node" + private static let talkService = "ai.openclawfoundation.app.talk" private static let instanceIdDefaultsKey = "node.instanceId" private static let preferredGatewayStableIDDefaultsKey = "gateway.preferredStableID" @@ -444,7 +444,7 @@ enum GatewaySettingsStore { enum GatewayDiagnostics { private static let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "GatewayDiag") - private static let queue = DispatchQueue(label: "ai.openclaw.gateway.diagnostics") + private static let queue = DispatchQueue(label: "ai.openclawfoundation.app.gateway.diagnostics") private static let maxLogBytes: Int64 = 512 * 1024 private static let keepLogBytes: Int64 = 256 * 1024 private static let logSizeCheckEveryWrites = 50 diff --git a/apps/ios/Sources/Push/PushRelayKeychainStore.swift b/apps/ios/Sources/Push/PushRelayKeychainStore.swift index a9fc9a36dc88..784e0e3c2eaf 100644 --- a/apps/ios/Sources/Push/PushRelayKeychainStore.swift +++ b/apps/ios/Sources/Push/PushRelayKeychainStore.swift @@ -13,7 +13,7 @@ private struct StoredPushRelayRegistrationState: Codable { } enum PushRelayRegistrationStore { - private static let service = "ai.openclaw.pushrelay" + private static let service = "ai.openclawfoundation.app.pushrelay" private static let registrationStateAccount = "registration-state" private static let appAttestKeyIDAccount = "app-attest-key-id" private static let appAttestedKeyIDAccount = "app-attested-key-id" diff --git a/apps/ios/Sources/Screen/ScreenRecordService.swift b/apps/ios/Sources/Screen/ScreenRecordService.swift index a6148731e153..11be9198e46a 100644 --- a/apps/ios/Sources/Screen/ScreenRecordService.swift +++ b/apps/ios/Sources/Screen/ScreenRecordService.swift @@ -56,7 +56,7 @@ final class ScreenRecordService: @unchecked Sendable { outPath: outPath) let state = CaptureState() - let recordQueue = DispatchQueue(label: "ai.openclaw.screenrecord") + let recordQueue = DispatchQueue(label: "ai.openclawfoundation.app.screenrecord") try await self.startCapture(state: state, config: config, recordQueue: recordQueue) try await Task.sleep(nanoseconds: UInt64(config.durationMs) * 1_000_000) diff --git a/apps/ios/Sources/Services/WatchConnectivityTransport.swift b/apps/ios/Sources/Services/WatchConnectivityTransport.swift index f96a0f1ed206..eee8ca602b98 100644 --- a/apps/ios/Sources/Services/WatchConnectivityTransport.swift +++ b/apps/ios/Sources/Services/WatchConnectivityTransport.swift @@ -26,7 +26,7 @@ private func sendReachableWatchMessage(_ payload: [String: Any], with session: W } final class WatchConnectivityTransport: NSObject, @unchecked Sendable { - private nonisolated static let logger = Logger(subsystem: "ai.openclaw", category: "watch.messaging") + private nonisolated static let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "watch.messaging") private let session: WCSession? private let callbacksLock = NSLock() diff --git a/apps/ios/Sources/Voice/RealtimeTalkRelaySession.swift b/apps/ios/Sources/Voice/RealtimeTalkRelaySession.swift index f8df5bc4882a..21f990e13c71 100644 --- a/apps/ios/Sources/Voice/RealtimeTalkRelaySession.swift +++ b/apps/ios/Sources/Voice/RealtimeTalkRelaySession.swift @@ -121,7 +121,7 @@ final class RealtimeTalkRelaySession { private let gateway: GatewayNodeSession private let options: Options private let pcmPlayer: PCMStreamingAudioPlaying - private let logger = Logger(subsystem: "ai.openclaw", category: "RealtimeTalkRelay") + private let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "RealtimeTalkRelay") private let onStatus: (String) -> Void private let onIssue: (TalkRuntimeIssue) -> Void private let onSpeakingChanged: (Bool) -> Void diff --git a/apps/ios/Sources/Voice/TalkModeManager.swift b/apps/ios/Sources/Voice/TalkModeManager.swift index 53bcd30595b0..0e8452f7f7a6 100644 --- a/apps/ios/Sources/Voice/TalkModeManager.swift +++ b/apps/ios/Sources/Voice/TalkModeManager.swift @@ -170,7 +170,7 @@ final class TalkModeManager: NSObject { private var incrementalSpeechPrefetch: IncrementalSpeechPrefetchState? private var incrementalSpeechPrefetchMonitorTask: Task? - private let logger = Logger(subsystem: "ai.openclaw", category: "TalkMode") + private let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "TalkMode") private static func nowSeconds() -> TimeInterval { ProcessInfo.processInfo.systemUptime diff --git a/apps/ios/Sources/Voice/TalkRealtimeWebRTCSession.swift b/apps/ios/Sources/Voice/TalkRealtimeWebRTCSession.swift index 6ebfa4879ec6..f062f3ed8772 100644 --- a/apps/ios/Sources/Voice/TalkRealtimeWebRTCSession.swift +++ b/apps/ios/Sources/Voice/TalkRealtimeWebRTCSession.swift @@ -17,7 +17,7 @@ protocol TalkRealtimeWebRTCSessionDelegate: AnyObject { @MainActor final class TalkRealtimeWebRTCSession: NSObject { - private static let logger = Logger(subsystem: "ai.openclaw", category: "TalkRealtimeWebRTC") + private static let logger = Logger(subsystem: "ai.openclawfoundation.app", category: "TalkRealtimeWebRTC") private static let consultToolName = "openclaw_agent_consult" private static let controlToolName = "openclaw_agent_control" private static let defaultOfferURL = "https://api.openai.com/v1/realtime/calls" diff --git a/apps/ios/Tests/GatewayConnectionControllerTests.swift b/apps/ios/Tests/GatewayConnectionControllerTests.swift index 233d58449ab8..bb2fdae21e51 100644 --- a/apps/ios/Tests/GatewayConnectionControllerTests.swift +++ b/apps/ios/Tests/GatewayConnectionControllerTests.swift @@ -371,15 +371,18 @@ import UIKit } @Test @MainActor func loadLastConnectionReadsSavedValues() { - let prior = KeychainStore.loadString(service: "ai.openclaw.gateway", account: "lastConnection") + let prior = KeychainStore.loadString(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") defer { if let prior { - _ = KeychainStore.saveString(prior, service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.saveString( + prior, + service: "ai.openclawfoundation.app.gateway", + account: "lastConnection") } else { - _ = KeychainStore.delete(service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.delete(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") } } - _ = KeychainStore.delete(service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.delete(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") GatewaySettingsStore.saveLastGatewayConnectionManual( host: "gateway.example.com", @@ -395,15 +398,18 @@ import UIKit } @Test @MainActor func loadLastConnectionReturnsNilForInvalidData() { - let prior = KeychainStore.loadString(service: "ai.openclaw.gateway", account: "lastConnection") + let prior = KeychainStore.loadString(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") defer { if let prior { - _ = KeychainStore.saveString(prior, service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.saveString( + prior, + service: "ai.openclawfoundation.app.gateway", + account: "lastConnection") } else { - _ = KeychainStore.delete(service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.delete(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") } } - _ = KeychainStore.delete(service: "ai.openclaw.gateway", account: "lastConnection") + _ = KeychainStore.delete(service: "ai.openclawfoundation.app.gateway", account: "lastConnection") // Plant legacy UserDefaults with invalid host/port to exercise migration + validation. withUserDefaults([ diff --git a/apps/ios/Tests/GatewaySettingsStoreTests.swift b/apps/ios/Tests/GatewaySettingsStoreTests.swift index 80f20b1d6097..ab3606ce43cf 100644 --- a/apps/ios/Tests/GatewaySettingsStoreTests.swift +++ b/apps/ios/Tests/GatewaySettingsStoreTests.swift @@ -7,8 +7,8 @@ private struct KeychainEntry: Hashable { let account: String } -private let gatewayService = "ai.openclaw.gateway" -private let nodeService = "ai.openclaw.node" +private let gatewayService = "ai.openclawfoundation.app.gateway" +private let nodeService = "ai.openclawfoundation.app.node" private let instanceIdEntry = KeychainEntry(service: nodeService, account: "instanceId") private let preferredGatewayEntry = KeychainEntry(service: gatewayService, account: "preferredStableID") private let lastGatewayEntry = KeychainEntry(service: gatewayService, account: "lastDiscoveredStableID") diff --git a/apps/ios/Tests/KeychainStoreTests.swift b/apps/ios/Tests/KeychainStoreTests.swift index e56f4aa35b5a..8e83200b894e 100644 --- a/apps/ios/Tests/KeychainStoreTests.swift +++ b/apps/ios/Tests/KeychainStoreTests.swift @@ -4,7 +4,7 @@ import Testing @Suite struct KeychainStoreTests { @Test func saveLoadUpdateDeleteRoundTrip() { - let service = "ai.openclaw.tests.\(UUID().uuidString)" + let service = "ai.openclawfoundation.app.tests.\(UUID().uuidString)" let account = "value" #expect(KeychainStore.delete(service: service, account: account)) diff --git a/apps/ios/fastlane/Appfile b/apps/ios/fastlane/Appfile index b0374fbd7167..7059a183bb7f 100644 --- a/apps/ios/fastlane/Appfile +++ b/apps/ios/fastlane/Appfile @@ -1,4 +1,4 @@ -app_identifier("ai.openclaw.client") +app_identifier("ai.openclawfoundation.app") # Auth is expected via App Store Connect API key. # Provide either: diff --git a/apps/ios/fastlane/Fastfile b/apps/ios/fastlane/Fastfile index 79d1f2f40d6b..cac16b5a48e8 100644 --- a/apps/ios/fastlane/Fastfile +++ b/apps/ios/fastlane/Fastfile @@ -4,7 +4,7 @@ require "json" default_platform(:ios) -BETA_APP_IDENTIFIER = "ai.openclaw.client" +BETA_APP_IDENTIFIER = "ai.openclawfoundation.app" def load_env_file(path) return unless File.exist?(path) diff --git a/apps/ios/fastlane/SETUP.md b/apps/ios/fastlane/SETUP.md index 059f250e8a7d..6c716189cf70 100644 --- a/apps/ios/fastlane/SETUP.md +++ b/apps/ios/fastlane/SETUP.md @@ -34,7 +34,7 @@ Important: `apps/ios/fastlane/.env` is only for Fastlane/App Store Connect auth Optional app targeting variables (helpful if Fastlane cannot auto-resolve app by bundle): ```bash -ASC_APP_IDENTIFIER=ai.openclaw.client +ASC_APP_IDENTIFIER=ai.openclawfoundation.app # or ASC_APP_ID=YOUR_APP_STORE_CONNECT_APP_ID ``` diff --git a/scripts/ios-beta-prepare.sh b/scripts/ios-beta-prepare.sh index 4101110316aa..305effba2933 100755 --- a/scripts/ios-beta-prepare.sh +++ b/scripts/ios-beta-prepare.sh @@ -159,11 +159,11 @@ write_generated_file "${BETA_XCCONFIG}" <