From 7f70aa100323af3f6ca421c86bb6b09ca48d6be9 Mon Sep 17 00:00:00 2001 From: Jamil Date: Sat, 25 Jan 2025 05:29:23 -0800 Subject: [PATCH] fix(apple): Ensure beginUpdatingResources doesn't block (#7864) `fetchResources` is an IPC call. As such, it could potentially take a long time to execute since the system may need to launch the XPC process to handle the call. Since this is called within a 1-second Timer whenever the user has the MenuBar open (macOS) or is viewing the ResourcesList (iOS), we need to run these IPC calls in a `Task.detached`. The resources themselves must be updated on the main thread because they're an `ObservableObject`, so a bit of refactoring is added to clean this up a bit. --- .../Sources/FirezoneKit/Stores/Store.swift | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/Store.swift b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/Store.swift index b8cc49c8b..d893e9b2f 100644 --- a/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/Store.swift +++ b/swift/apple/FirezoneKit/Sources/FirezoneKit/Stores/Store.swift @@ -214,15 +214,23 @@ public final class Store: ObservableObject { func beginUpdatingResources(callback: @escaping (ResourceList) -> Void) { Log.log("\(#function)") - self.vpnConfigurationManager.fetchResources(callback: callback) - let intervalInSeconds: TimeInterval = 1 - let timer = Timer(timeInterval: intervalInSeconds, repeats: true) { [weak self] _ in - Task.detached { + // Define the Timer's closure + let updateResources: @Sendable (Timer) -> Void = { _timer in + Task.detached { [weak self] in await self?.vpnConfigurationManager.fetchResources(callback: callback) } } + + // Configure the timer + let intervalInSeconds: TimeInterval = 1 + let timer = Timer(timeInterval: intervalInSeconds, repeats: true, block: updateResources) + + // Schedule the timer on the main runloop RunLoop.main.add(timer, forMode: .common) resourcesTimer = timer + + // We're impatient, make one call now + updateResources(timer) } func endUpdatingResources() {