From 8eb5a028495e187299d0aab14560a5ba6625c355 Mon Sep 17 00:00:00 2001 From: Brent Simmons Date: Tue, 26 Mar 2024 22:34:16 -0700 Subject: [PATCH] Convert validateCredentials to async await. --- Account/Sources/Account/Account.swift | 37 ++++++++++++++----- Account/Sources/Account/AccountDelegate.swift | 2 +- .../CloudKit/CloudKitAccountDelegate.swift | 5 ++- .../Feedbin/FeedbinAccountDelegate.swift | 19 +++++++++- .../Feedly/FeedlyAccountDelegate.swift | 5 ++- .../LocalAccount/LocalAccountDelegate.swift | 5 ++- .../NewsBlur/NewsBlurAccountDelegate.swift | 17 ++++++++- .../ReaderAPI/ReaderAPIAccountDelegate.swift | 18 ++++++++- 8 files changed, 88 insertions(+), 20 deletions(-) diff --git a/Account/Sources/Account/Account.swift b/Account/Sources/Account/Account.swift index 7b3975439..207291695 100644 --- a/Account/Sources/Account/Account.swift +++ b/Account/Sources/Account/Account.swift @@ -358,15 +358,34 @@ public enum FetchType { } public static func validateCredentials(transport: Transport = URLSession.webserviceTransport(), type: AccountType, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { - switch type { - case .feedbin: - FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, secretsProvider: secretsProvider, completion: completion) - case .newsBlur: - NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials, secretsProvider: secretsProvider, completion: completion) - case .freshRSS, .inoreader, .bazQux, .theOldReader: - ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider, completion: completion) - default: - break + + Task { @MainActor in + + do { + switch type { + + case .feedbin: + + let credentials = try await FeedbinAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) + completion(.success(credentials)) + + case .newsBlur: + + let credentials = try await NewsBlurAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) + completion(.success(credentials)) + + case .freshRSS, .inoreader, .bazQux, .theOldReader: + + let credentials = try await ReaderAPIAccountDelegate.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) + completion(.success(credentials)) + + default: + completion(.success(nil)) + } + + } catch { + completion(.failure(error)) + } } } diff --git a/Account/Sources/Account/AccountDelegate.swift b/Account/Sources/Account/AccountDelegate.swift index 15e2536d5..0f9686c9f 100644 --- a/Account/Sources/Account/AccountDelegate.swift +++ b/Account/Sources/Account/AccountDelegate.swift @@ -51,7 +51,7 @@ import Secrets func accountWillBeDeleted(_ account: Account) - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? /// Suspend all network activity func suspendNetwork() diff --git a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift index b68c83696..cb34f1322 100644 --- a/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift +++ b/Account/Sources/Account/CloudKit/CloudKitAccountDelegate.swift @@ -548,8 +548,9 @@ enum CloudKitAccountDelegateError: LocalizedError { articlesZone.resetChangeToken() } - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: (Result) -> Void) { - return completion(.success(nil)) + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + + return nil } // MARK: Suspend and Resume (for iOS) diff --git a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift index 5233b374b..068f05376 100644 --- a/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift +++ b/Account/Sources/Account/Feedbin/FeedbinAccountDelegate.swift @@ -647,8 +647,23 @@ final class FeedbinAccountDelegate: AccountDelegate { func accountWillBeDeleted(_ account: Account) { } - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { - + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + + try await withCheckedThrowingContinuation { continuation in + + self.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) { result in + switch result { + case .success(let credentials): + continuation.resume(returning: credentials) + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { + let caller = FeedbinAPICaller(transport: transport) caller.credentials = credentials caller.validateCredentials() { result in diff --git a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift index 198c9d034..e2759c1b5 100644 --- a/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift +++ b/Account/Sources/Account/Feedly/FeedlyAccountDelegate.swift @@ -629,9 +629,10 @@ final class FeedlyAccountDelegate: AccountDelegate { MainThreadOperationQueue.shared.add(logout) } - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + assertionFailure("An `account` instance should enqueue an \(FeedlyRefreshAccessTokenOperation.self) instead.") - completion(.success(credentials)) + return credentials } // MARK: Suspend and Resume (for iOS) diff --git a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift index 1e1641b72..74510912e 100644 --- a/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift +++ b/Account/Sources/Account/LocalAccount/LocalAccountDelegate.swift @@ -161,8 +161,9 @@ final class LocalAccountDelegate: AccountDelegate { func accountWillBeDeleted(_ account: Account) { } - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: (Result) -> Void) { - return completion(.success(nil)) + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + + return nil } // MARK: Suspend and Resume (for iOS) diff --git a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift index b564a2b75..40914eb26 100644 --- a/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift +++ b/Account/Sources/Account/NewsBlur/NewsBlurAccountDelegate.swift @@ -689,7 +689,22 @@ final class NewsBlurAccountDelegate: AccountDelegate { caller.logout() { _ in } } - class func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: @escaping (Result) -> ()) { + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + + try await withCheckedThrowingContinuation { continuation in + + self.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) { result in + switch result { + case .success(let credentials): + continuation.resume(returning: credentials) + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private class func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL? = nil, secretsProvider: SecretsProvider, completion: @escaping (Result) -> ()) { let caller = NewsBlurAPICaller(transport: transport) caller.credentials = credentials caller.validateCredentials() { result in diff --git a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift index 7443a623b..b4a6af595 100644 --- a/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift +++ b/Account/Sources/Account/ReaderAPI/ReaderAPIAccountDelegate.swift @@ -701,7 +701,23 @@ final class ReaderAPIAccountDelegate: AccountDelegate { func accountWillBeDeleted(_ account: Account) { } - static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { + static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider) async throws -> Credentials? { + + try await withCheckedThrowingContinuation { continuation in + + self.validateCredentials(transport: transport, credentials: credentials, endpoint: endpoint, secretsProvider: secretsProvider) { result in + + switch result { + case .success(let credentials): + continuation.resume(returning: credentials) + case .failure(let error): + continuation.resume(throwing: error) + } + } + } + } + + private static func validateCredentials(transport: Transport, credentials: Credentials, endpoint: URL?, secretsProvider: SecretsProvider, completion: @escaping (Result) -> Void) { guard let endpoint = endpoint else { completion(.failure(TransportError.noURL)) return