diff options
4 files changed, 31 insertions, 24 deletions
diff --git a/ios/MullvadVPN/TunnelManager/TunnelStore.swift b/ios/MullvadVPN/TunnelManager/TunnelStore.swift index 0344175033..2872bf091a 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelStore.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelStore.swift @@ -48,7 +48,7 @@ final class TunnelStore: TunnelStoreProtocol, TunnelStatusObserver, @unchecked S return persistentTunnels } - func loadPersistentTunnels(completion: @escaping (Error?) -> Void) { + func loadPersistentTunnels(completion: @escaping @Sendable (Error?) -> Void) { TunnelProviderManagerType.loadAllFromPreferences { managers, error in self.lock.lock() defer { diff --git a/ios/MullvadVPN/TunnelManager/VPNConnectionProtocol.swift b/ios/MullvadVPN/TunnelManager/VPNConnectionProtocol.swift index 3465b7e19c..8e28a82d06 100644 --- a/ios/MullvadVPN/TunnelManager/VPNConnectionProtocol.swift +++ b/ios/MullvadVPN/TunnelManager/VPNConnectionProtocol.swift @@ -20,11 +20,11 @@ protocol VPNTunnelProviderManagerProtocol: Equatable { init() - func loadFromPreferences(completionHandler: @escaping (Error?) -> Void) - func saveToPreferences(completionHandler: ((Error?) -> Void)?) - func removeFromPreferences(completionHandler: ((Error?) -> Void)?) + func loadFromPreferences(completionHandler: @escaping @Sendable (Error?) -> Void) + func saveToPreferences(completionHandler: (@Sendable (Error?) -> Void)?) + func removeFromPreferences(completionHandler: (@Sendable (Error?) -> Void)?) - static func loadAllFromPreferences(completionHandler: @escaping ([SelfType]?, Error?) -> Void) + static func loadAllFromPreferences(completionHandler: @escaping @Sendable ([SelfType]?, Error?) -> Void) } protocol VPNConnectionProtocol: NSObject { diff --git a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewModel.swift b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewModel.swift index e42fa412b6..1f73016e27 100644 --- a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewModel.swift +++ b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewModel.swift @@ -7,7 +7,7 @@ // import Foundation -import SwiftUICore +import SwiftUI protocol AccountDeletionBackEnd { var accountNumber: String? { get } diff --git a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift index 7a26115807..05ba1bc3f6 100644 --- a/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift +++ b/ios/PacketTunnel/PacketTunnelProvider/PacketTunnelProvider.swift @@ -152,7 +152,10 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable { ) } - override func startTunnel(options: [String: NSObject]? = nil) async throws { + override func startTunnel( + options: [String: NSObject]? = nil, + completionHandler: @escaping @Sendable ((any Error)?) -> Void + ) { let startOptions = parseStartOptions(options ?? [:]) startObservingActorState() @@ -163,25 +166,29 @@ class PacketTunnelProvider: NEPacketTunnelProvider, @unchecked Sendable { actor.start(options: startOptions) - for await state in await actor.observedStates { - switch state { - case .connected, .disconnected, .error: - return - case let .connecting(connectionState): - // Give the tunnel a few tries to connect, otherwise return immediately. This will enable VPN in - // device settings, but the app will still report the true state via ObservedState over IPC. - // In essence, this prevents the 60s tunnel timeout to trigger. - if connectionState.connectionAttemptCount > 1 { + Task { + for await state in await actor.observedStates { + switch state { + case .connected, .disconnected, .error: + completionHandler(nil) + return + case let .connecting(connectionState): + // Give the tunnel a few tries to connect, otherwise return immediately. This will enable VPN in + // device settings, but the app will still report the true state via ObservedState over IPC. + // In essence, this prevents the 60s tunnel timeout to trigger. + if connectionState.connectionAttemptCount > 1 { + completionHandler(nil) + return + } + case .negotiatingEphemeralPeer: + // When negotiating ephemeral peers, allow the connection to go through immediately. + // Otherwise, the in-tunnel TCP connection will never become ready as the OS doesn't let + // any traffic through until this function returns, which would prevent negotiating ephemeral peers + // from an unconnected state. return + default: + completionHandler(nil) } - case .negotiatingEphemeralPeer: - // When negotiating ephemeral peers, allow the connection to go through immediately. - // Otherwise, the in-tunnel TCP connection will never become ready as the OS doesn't let - // any traffic through until this function returns, which would prevent negotiating ephemeral peers - // from an unconnected state. - return - default: - break } } } |
