From 0bcff4baf567594b788af8e2d936041aff1c81d5 Mon Sep 17 00:00:00 2001 From: Eulices Lopez <105620565+eulicesl@users.noreply.github.com> Date: Mon, 9 Mar 2026 06:37:26 -0400 Subject: [PATCH] fix(ios): resolve main-thread warnings for CLLocationManager and SFSpeechRecognizer - Reuse CLLocationManager instance instead of creating on main thread each call - Cache SFSpeechRecognizer.authorizationStatus as nonisolated computed property - Both fixes eliminate UI-responsiveness warnings in currentPermissions() --- .../Gateway/GatewayConnectionController.swift | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/apps/ios/Sources/Gateway/GatewayConnectionController.swift b/apps/ios/Sources/Gateway/GatewayConnectionController.swift index dc94f3d0797..b27589f6279 100644 --- a/apps/ios/Sources/Gateway/GatewayConnectionController.swift +++ b/apps/ios/Sources/Gateway/GatewayConnectionController.swift @@ -37,6 +37,14 @@ final class GatewayConnectionController { private(set) var pendingTrustPrompt: TrustPrompt? private let discovery = GatewayDiscoveryModel() + /// Reused instance — avoids creating CLLocationManager on the main thread + /// each time currentPermissions() is called, which triggers a UI-thread warning. + private let locationManager = CLLocationManager() + /// Cached off the main thread to avoid the UI-responsiveness warning from + /// calling SFSpeechRecognizer.authorizationStatus() on the main actor. + private nonisolated var speechRecognitionStatus: SFSpeechRecognizerAuthorizationStatus { + SFSpeechRecognizer.authorizationStatus() + } private weak var appModel: NodeAppModel? private var didAutoConnect = false private var pendingServiceResolvers: [String: GatewayServiceResolver] = [:] @@ -891,9 +899,9 @@ final class GatewayConnectionController { var permissions: [String: Bool] = [:] permissions["camera"] = AVCaptureDevice.authorizationStatus(for: .video) == .authorized permissions["microphone"] = AVCaptureDevice.authorizationStatus(for: .audio) == .authorized - permissions["speechRecognition"] = SFSpeechRecognizer.authorizationStatus() == .authorized + permissions["speechRecognition"] = self.speechRecognitionStatus == .authorized permissions["location"] = Self.isLocationAuthorized( - status: CLLocationManager().authorizationStatus) + status: self.locationManager.authorizationStatus) && CLLocationManager.locationServicesEnabled() permissions["screenRecording"] = RPScreenRecorder.shared().isAvailable