From f786eaee571db0853afb9fbe7cb6fc91ce6182e8 Mon Sep 17 00:00:00 2001 From: Andrew Bulhak Date: Thu, 1 Feb 2024 11:17:45 +0100 Subject: [PATCH 1/3] Refactor TunnelManager account setting methods replacing callbacks with async --- .../Coordinators/AccountCoordinator.swift | 5 ++- .../Coordinators/ApplicationCoordinator.swift | 6 ++- .../TunnelManager/TunnelManager.swift | 39 ++++++++----------- .../Account/AccountInteractor.swift | 6 +-- .../AccountDeletionInteractor.swift | 4 +- .../AccountDeletionViewController.swift | 9 +++-- .../Login/LoginInteractor.swift | 13 ++----- .../Login/LoginViewController.swift | 24 ++++++------ .../RedeemVoucherInteractor.swift | 14 ++----- .../RedeemVoucherViewController.swift | 9 +++-- 10 files changed, 60 insertions(+), 69 deletions(-) diff --git a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift index 3c58e3528740..9a529a5d9a46 100644 --- a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift @@ -141,8 +141,9 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting { ) let alertPresenter = AlertPresenter(context: self) - - interactor.logout { + + Task { + await interactor.logout() DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in guard let self else { return } diff --git a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift index 719c97066af3..ed61054537fa 100644 --- a/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/ApplicationCoordinator.swift @@ -342,8 +342,10 @@ final class ApplicationCoordinator: Coordinator, Presenting, RootContainerViewCo } private func logoutRevokedDevice() { - tunnelManager.unsetAccount { [weak self] in - self?.continueFlow(animated: true) + Task { [weak self] in + guard let self else { return } + await tunnelManager.unsetAccount() + continueFlow(animated: true) } } diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift index 960cfd2a8af5..41309a323859 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift @@ -311,19 +311,13 @@ final class TunnelManager: StorePaymentObserver { operationQueue.addOperation(operation) } - func setNewAccount(completion: @escaping (Result) -> Void) { - setAccount(action: .new) { result in - completion(result.map { $0! }) - } + + func setNewAccount() async throws -> StoredAccountData { + try await setAccount(action: .new)! } - func setExistingAccount( - accountNumber: String, - completion: @escaping (Result) -> Void - ) { - setAccount(action: .existing(accountNumber)) { result in - completion(result.map { $0! }) - } + func setExistingAccount(accountNumber: String) async throws -> StoredAccountData { + try await setAccount(action: .existing(accountNumber))! } private func setAccount( @@ -373,13 +367,19 @@ final class TunnelManager: StorePaymentObserver { operationQueue.addOperation(operation) } - - func unsetAccount(completionHandler: @escaping () -> Void) { - setAccount(action: .unset) { _ in - completionHandler() + + private func setAccount(action: SetAccountAction) async throws -> StoredAccountData? { + try await withCheckedThrowingContinuation { continuation in + setAccount(action: action) { result in + continuation.resume(with: result) + } } } + func unsetAccount() async { + _ = try? await setAccount(action: .unset) + } + func updateAccountData(_ completionHandler: ((Error?) -> Void)? = nil) { let operation = UpdateAccountDataOperation( dispatchQueue: internalQueue, @@ -435,13 +435,8 @@ final class TunnelManager: StorePaymentObserver { return operation } - func deleteAccount( - accountNumber: String, - completion: ((Error?) -> Void)? = nil - ) { - setAccount(action: .delete(accountNumber)) { result in - completion?(result.error) - } + func deleteAccount(accountNumber: String) async throws { + _ = try await setAccount(action: .delete(accountNumber)) } func updateDeviceData(_ completionHandler: ((Error?) -> Void)? = nil) { diff --git a/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift b/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift index 05d2d4046507..55a62121796c 100644 --- a/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift +++ b/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift @@ -52,9 +52,9 @@ final class AccountInteractor { var deviceState: DeviceState { tunnelManager.deviceState } - - func logout(_ completion: @escaping () -> Void) { - tunnelManager.unsetAccount(completionHandler: completion) + + func logout() async { + await tunnelManager.unsetAccount() } func addPayment(_ payment: SKPayment, for accountNumber: String) { diff --git a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionInteractor.swift b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionInteractor.swift index 1562c013b835..f0cf80ab8709 100644 --- a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionInteractor.swift +++ b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionInteractor.swift @@ -48,7 +48,7 @@ class AccountDeletionInteractor { } } - func delete(accountNumber: String, completionHandler: @escaping (Error?) -> Void) { - tunnelManager.deleteAccount(accountNumber: accountNumber, completion: completionHandler) + func delete(accountNumber: String) async throws { + try await tunnelManager.deleteAccount(accountNumber: accountNumber) } } diff --git a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewController.swift b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewController.swift index cea4095b75c1..6479134b1426 100644 --- a/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewController.swift +++ b/ios/MullvadVPN/View controllers/AccountDeletion/AccountDeletionViewController.swift @@ -62,14 +62,15 @@ class AccountDeletionViewController: UIViewController { private func submit(accountNumber: String) { contentView.state = .loading - interactor.delete(accountNumber: accountNumber) { [weak self] error in + Task { [weak self] in guard let self else { return } - guard let error else { + do { + try await interactor.delete(accountNumber: accountNumber) self.contentView.state = .initial self.delegate?.deleteAccountDidSucceed(controller: self) - return + } catch { + self.contentView.state = .failure(error) } - self.contentView.state = .failure(error) } } } diff --git a/ios/MullvadVPN/View controllers/Login/LoginInteractor.swift b/ios/MullvadVPN/View controllers/Login/LoginInteractor.swift index 4ec56074b1f8..0f69fe96fdbb 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginInteractor.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginInteractor.swift @@ -21,17 +21,12 @@ final class LoginInteractor { self.tunnelManager = tunnelManager } - func setAccount(accountNumber: String, completion: @escaping (Error?) -> Void) { - tunnelManager.setExistingAccount(accountNumber: accountNumber) { result in - completion(result.error) - } + func setAccount(accountNumber: String) async throws { + _ = try await tunnelManager.setExistingAccount(accountNumber: accountNumber) } - func createAccount(completion: @escaping (Result) -> Void) { - tunnelManager.setNewAccount { [weak self] result in - self?.didCreateAccount?() - completion(result.map { $0.number }) - } + func createAccount() async throws -> String { + try await tunnelManager.setNewAccount().number } func getLastUsedAccount() -> String? { diff --git a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift index e2bde94b0cb1..30376ddebd2f 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift @@ -193,21 +193,21 @@ class LoginViewController: UIViewController, RootContainment { func start(action: LoginAction) { beginLogin(action) - - switch action { - case .createAccount: - interactor.createAccount { [weak self] result in - if let newAccountNumber = result.value { - self?.contentView.accountInputGroup.setAccount(newAccountNumber) + Task { [weak self] in + guard let self else { return } + do { + switch action { + case .createAccount: + self.contentView.accountInputGroup.setAccount(try await interactor.createAccount()) + + case let .useExistingAccount(accountNumber): + try await interactor.setAccount(accountNumber: accountNumber) } - - self?.endLogin(action: action, error: result.error) + self.endLogin(action: action, error: nil) + } catch { + self.endLogin(action: action, error: error) } - case let .useExistingAccount(accountNumber): - interactor.setAccount(accountNumber: accountNumber) { [weak self] error in - self?.endLogin(action: action, error: error) - } } } diff --git a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherInteractor.swift b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherInteractor.swift index 26da26f14723..88011370057a 100644 --- a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherInteractor.swift +++ b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherInteractor.swift @@ -46,16 +46,10 @@ final class RedeemVoucherInteractor { }) } - func logout(completionHandler: @escaping () -> Void) { - preferredAccountNumber.flatMap { accountNumber in - tunnelManager.unsetAccount { [weak self] in - guard let self else { - return - } - completionHandler() - didLogout?(accountNumber) - } - } + func logout() async { + guard let accountNumber = preferredAccountNumber else { return } + await tunnelManager.unsetAccount() + didLogout?(accountNumber) } func cancelAll() { diff --git a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift index d5757b30268d..805aaa0adddb 100644 --- a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift +++ b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift @@ -137,9 +137,12 @@ class RedeemVoucherViewController: UIViewController, UINavigationControllerDeleg contentView.isEditing = false contentView.state = .logout - - interactor.logout { [weak self] in - self?.contentView.state = .initial + + Task { + [weak self] in + guard let self else { return } + await interactor.logout() + contentView.state = .initial } } } From 0bdb40bb3287ac5add44c9ed8d7b059703719def Mon Sep 17 00:00:00 2001 From: Andrew Bulhak Date: Fri, 2 Feb 2024 10:06:55 +0100 Subject: [PATCH 2/3] Whitespace fixes --- ios/MullvadVPN/Coordinators/AccountCoordinator.swift | 2 +- ios/MullvadVPN/TunnelManager/TunnelManager.swift | 3 +-- .../View controllers/Account/AccountInteractor.swift | 2 +- .../View controllers/Login/LoginViewController.swift | 1 - 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift index 9a529a5d9a46..cb4ce984782c 100644 --- a/ios/MullvadVPN/Coordinators/AccountCoordinator.swift +++ b/ios/MullvadVPN/Coordinators/AccountCoordinator.swift @@ -141,7 +141,7 @@ final class AccountCoordinator: Coordinator, Presentable, Presenting { ) let alertPresenter = AlertPresenter(context: self) - + Task { await interactor.logout() DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(1)) { [weak self] in diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift index 41309a323859..34e9a603a34f 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift @@ -310,7 +310,6 @@ final class TunnelManager: StorePaymentObserver { operationQueue.addOperation(operation) } - func setNewAccount() async throws -> StoredAccountData { try await setAccount(action: .new)! @@ -367,7 +366,7 @@ final class TunnelManager: StorePaymentObserver { operationQueue.addOperation(operation) } - + private func setAccount(action: SetAccountAction) async throws -> StoredAccountData? { try await withCheckedThrowingContinuation { continuation in setAccount(action: action) { result in diff --git a/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift b/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift index 55a62121796c..f5cc3a77a52b 100644 --- a/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift +++ b/ios/MullvadVPN/View controllers/Account/AccountInteractor.swift @@ -52,7 +52,7 @@ final class AccountInteractor { var deviceState: DeviceState { tunnelManager.deviceState } - + func logout() async { await tunnelManager.unsetAccount() } diff --git a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift index 30376ddebd2f..a2879b098a44 100644 --- a/ios/MullvadVPN/View controllers/Login/LoginViewController.swift +++ b/ios/MullvadVPN/View controllers/Login/LoginViewController.swift @@ -207,7 +207,6 @@ class LoginViewController: UIViewController, RootContainment { } catch { self.endLogin(action: action, error: error) } - } } From 83347b36b0e762b67279e532d7fcaa1a2942de1b Mon Sep 17 00:00:00 2001 From: Andrew Bulhak Date: Fri, 2 Feb 2024 10:10:23 +0100 Subject: [PATCH 3/3] Whitespace fixes --- ios/MullvadVPN/TunnelManager/TunnelManager.swift | 2 +- .../RedeemVoucher/RedeemVoucherViewController.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/MullvadVPN/TunnelManager/TunnelManager.swift b/ios/MullvadVPN/TunnelManager/TunnelManager.swift index 34e9a603a34f..b0c55cdfad37 100644 --- a/ios/MullvadVPN/TunnelManager/TunnelManager.swift +++ b/ios/MullvadVPN/TunnelManager/TunnelManager.swift @@ -310,7 +310,7 @@ final class TunnelManager: StorePaymentObserver { operationQueue.addOperation(operation) } - + func setNewAccount() async throws -> StoredAccountData { try await setAccount(action: .new)! } diff --git a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift index 805aaa0adddb..d88cc1e4cad4 100644 --- a/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift +++ b/ios/MullvadVPN/View controllers/RedeemVoucher/RedeemVoucherViewController.swift @@ -137,7 +137,7 @@ class RedeemVoucherViewController: UIViewController, UINavigationControllerDeleg contentView.isEditing = false contentView.state = .logout - + Task { [weak self] in guard let self else { return }