diff --git a/Coder Desktop/Coder Desktop/SystemExtension.swift b/Coder Desktop/Coder Desktop/SystemExtension.swift index 0bddbac..bc81bd1 100644 --- a/Coder Desktop/Coder Desktop/SystemExtension.swift +++ b/Coder Desktop/Coder Desktop/SystemExtension.swift @@ -29,6 +29,10 @@ protocol SystemExtensionAsyncRecorder: Sendable { extension CoderVPNService: SystemExtensionAsyncRecorder { func recordSystemExtensionState(_ state: SystemExtensionState) async { sysExtnState = state + if state == .installed { + // system extension was successfully installed, so we don't need the delegate any more + systemExtnDelegate = nil + } } var extensionBundle: Bundle { @@ -71,6 +75,7 @@ extension CoderVPNService: SystemExtensionAsyncRecorder { queue: .main ) let delegate = SystemExtensionDelegate(asyncDelegate: self) + systemExtnDelegate = delegate request.delegate = delegate OSSystemExtensionManager.shared.submitRequest(request) logger.info("submitted SystemExtension request with bundleID: \(bundleID)") @@ -87,6 +92,7 @@ class SystemExtensionDelegate: init(asyncDelegate: AsyncDelegate) { self.asyncDelegate = asyncDelegate + super.init() logger.info("SystemExtensionDelegate initialized") } diff --git a/Coder Desktop/Coder Desktop/VPNService.swift b/Coder Desktop/Coder Desktop/VPNService.swift index cb5cf55..9d478a7 100644 --- a/Coder Desktop/Coder Desktop/VPNService.swift +++ b/Coder Desktop/Coder Desktop/VPNService.swift @@ -58,6 +58,11 @@ final class CoderVPNService: NSObject, VPNService { @Published var agents: [Agent] = [] + // systemExtnDelegate holds a reference to the SystemExtensionDelegate so that it doesn't get + // garbage collected while the OSSystemExtensionRequest is in flight, since the OS framework + // only stores a weak reference to the delegate. + var systemExtnDelegate: SystemExtensionDelegate? + override init() { super.init() installSystemExtension()