diff --git a/Account/Sources/Account/Feedly/FeedlyAPICaller.swift b/Account/Sources/Account/Feedly/FeedlyAPICaller.swift index 38be1b88b..bc2f89a63 100644 --- a/Account/Sources/Account/Feedly/FeedlyAPICaller.swift +++ b/Account/Sources/Account/Feedly/FeedlyAPICaller.swift @@ -553,42 +553,15 @@ extension FeedlyAPICaller: FeedlySearchService { extension FeedlyAPICaller: FeedlyLogoutService { - func logout(completion: @escaping (Result) -> ()) { - guard !isSuspended else { - return DispatchQueue.main.async { - completion(.failure(TransportError.suspended)) - } - } - - guard let accessToken = credentials?.secret else { - return DispatchQueue.main.async { - completion(.failure(CredentialsError.incompleteCredentials)) - } - } - var components = baseURLComponents - components.path = "/v3/auth/logout" - - guard let url = components.url else { - fatalError("\(components) does not produce a valid URL.") - } - - var request = URLRequest(url: url) - request.httpMethod = "POST" - request.addValue("application/json", forHTTPHeaderField: HTTPRequestHeader.contentType) - request.addValue("application/json", forHTTPHeaderField: "Accept-Type") - request.addValue("OAuth \(accessToken)", forHTTPHeaderField: HTTPRequestHeader.authorization) - - send(request: request, resultType: String.self, dateDecoding: .millisecondsSince1970, keyDecoding: .convertFromSnakeCase) { result in - switch result { - case .success(let (httpResponse, _)): - if httpResponse.statusCode == 200 { - completion(.success(())) - } else { - completion(.failure(URLError(.cannotDecodeContentData))) - } - case .failure(let error): - completion(.failure(error)) - } + func logout() async throws { + + guard !isSuspended else { throw TransportError.suspended } + + let request = try urlRequest(path: "/v3/auth/logout", method: HTTPMethod.post, includeJSONHeaders: true, includeOAuthToken: true) + + let (httpResponse, _) = try await send(request: request, resultType: String.self) + if httpResponse.statusCode != HTTPResponseCode.OK { + throw URLError(.cannotDecodeContentData) } } } diff --git a/Feedly/Sources/Feedly/Operations/FeedlyLogoutOperation.swift b/Feedly/Sources/Feedly/Operations/FeedlyLogoutOperation.swift index eaf795075..78336014a 100644 --- a/Feedly/Sources/Feedly/Operations/FeedlyLogoutOperation.swift +++ b/Feedly/Sources/Feedly/Operations/FeedlyLogoutOperation.swift @@ -10,7 +10,8 @@ import Foundation import os.log public protocol FeedlyLogoutService { - func logout(completion: @escaping (Result) -> ()) + + @MainActor func logout() async throws } public final class FeedlyLogoutOperation: FeedlyOperation { @@ -24,27 +25,24 @@ public final class FeedlyLogoutOperation: FeedlyOperation { } public override func run() { - os_log("Requesting logout of Feedly account.") - service.logout(completion: didCompleteLogout(_:)) - } - - func didCompleteLogout(_ result: Result) { - assert(Thread.isMainThread) - switch result { - case .success: - os_log("Logged out of Feedly account.") -// do { -// // TODO: fix removing credentials -//// try account.removeCredentials(type: .oauthAccessToken) -//// try account.removeCredentials(type: .oauthRefreshToken) -// } catch { -// // oh well, we tried our best. -// } - didFinish() - - case .failure(let error): - os_log("Logout failed because %{public}@.", error as NSError) - didFinish(with: error) + + Task { @MainActor in + + do { + os_log("Requesting logout of Feedly account.") + try await service.logout() + os_log("Logged out of Feedly account.") + + // TODO: fix removing credentials +// try account.removeCredentials(type: .oauthAccessToken) +// try account.removeCredentials(type: .oauthRefreshToken) + + didFinish() + + } catch { + os_log("Logout failed because %{public}@.", error as NSError) + didFinish(with: error) + } } } }