From 311d694822a0a137643489d77b2f7fff60de8088 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Tue, 21 Jun 2022 16:21:21 -0700 Subject: [PATCH] update validate username publisher to async --- .../Registration/CreateProfileView.swift | 26 +- .../DataService/Mutations/SaveArticle.swift | 224 ------------------ .../Queries/ValidateUsernameQuery.swift | 23 +- 3 files changed, 23 insertions(+), 250 deletions(-) delete mode 100644 apple/OmnivoreKit/Sources/Services/DataService/Mutations/SaveArticle.swift diff --git a/apple/OmnivoreKit/Sources/App/Views/Registration/CreateProfileView.swift b/apple/OmnivoreKit/Sources/App/Views/Registration/CreateProfileView.swift index db73ce795..2b8e71003 100644 --- a/apple/OmnivoreKit/Sources/App/Views/Registration/CreateProfileView.swift +++ b/apple/OmnivoreKit/Sources/App/Views/Registration/CreateProfileView.swift @@ -53,29 +53,27 @@ import Views return } - dataService.validateUsernamePublisher(username: username).sink( - receiveCompletion: { [weak self] completion in - guard case let .failure(usernameError) = completion else { return } + Task { + do { + try await dataService.validateUsernamePublisher(username: username) + } catch { + let usernameError = (error as? UsernameAvailabilityError) ?? .unknown switch usernameError { case .tooShort: - self?.potentialUsernameStatus = .tooShort + potentialUsernameStatus = .tooShort case .tooLong: - self?.potentialUsernameStatus = .tooLong + potentialUsernameStatus = .tooLong case .invalidPattern: - self?.potentialUsernameStatus = .invalidPattern + potentialUsernameStatus = .invalidPattern case .nameUnavailable: - self?.potentialUsernameStatus = .unavailable + potentialUsernameStatus = .unavailable case .internalServer, .unknown: - self?.loginError = .unknown + loginError = .unknown case .network: - self?.loginError = .network + loginError = .network } - }, - receiveValue: { [weak self] in - self?.potentialUsernameStatus = .available } - ) - .store(in: &subscriptions) + } } func submitProfile(userProfile: UserProfile, authenticator: Authenticator) async { diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SaveArticle.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SaveArticle.swift deleted file mode 100644 index 2c0766899..000000000 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SaveArticle.swift +++ /dev/null @@ -1,224 +0,0 @@ -import Combine -import Foundation -import Models -import SwiftGraphQL - -public enum SaveArticleStatus { - case succeeeded - case processing(jobId: String) - case failed - - static func make(jobId: String, savingStatus: Enums.ArticleSavingRequestStatus) -> SaveArticleStatus { - switch savingStatus { - case .processing: - return .processing(jobId: jobId) - case .succeeded: - return .succeeeded - case .failed: - return .failed - } - } -} - -public extension Networker { - func articleSaveStatus(jobId: String) -> AnyPublisher { - enum QueryResult { - case saved(status: SaveArticleStatus) - case error(errorCode: Enums.ArticleSavingRequestErrorCode) - } - - let selection = Selection { - try $0.on( - articleSavingRequestError: .init { .error(errorCode: (try? $0.errorCodes().first) ?? .notFound) }, - articleSavingRequestSuccess: .init { - .saved( - status: try $0.articleSavingRequest( - selection: .init { - SaveArticleStatus.make( - jobId: try $0.id(), - savingStatus: try $0.status() - ) - } - ) - ) - } - ) - } - - let query = Selection.Query { - try $0.articleSavingRequest(id: jobId, selection: selection) - } - - let path = appEnvironment.graphqlPath - let headers = defaultHeaders - - return Deferred { - Future { promise in - send(query, to: path, headers: headers) { result in - switch result { - case let .success(payload): - if let graphqlError = payload.errors { - promise(.failure(.unknown(description: graphqlError.first.debugDescription))) - } - - switch payload.data { - case let .saved(status): - promise(.success(status)) - case let .error(errorCode: errorCode): - switch errorCode { - case .unauthorized: - promise(.failure(.unauthorized)) - case .notFound: - promise(.failure(.badData)) - } - } - case let .failure(error): - promise(.failure(SaveArticleError.make(from: error))) - } - } - } - } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() - } -} - -public extension DataService { - // swiftlint:disable:next function_body_length - func saveArticlePublisher( - pageScrapePayload: PageScrapePayload, - uploadFileId: String? - ) -> AnyPublisher { - enum MutationResult { - case saved(created: Bool) - case error(errorCode: Enums.CreateArticleErrorCode) - } - - let preparedDocument: InputObjects.PreparedDocumentInput? = { - if case let .html(html, title, _) = pageScrapePayload.contentType { - return InputObjects.PreparedDocumentInput( - document: html, - pageInfo: InputObjects.PageInfoInput(title: OptionalArgument(title)) - ) - } - return nil - }() - - let input = InputObjects.CreateArticleInput( - preparedDocument: OptionalArgument(preparedDocument), - uploadFileId: uploadFileId != nil ? .present(uploadFileId!) : .null(), - url: pageScrapePayload.url - ) - - let selection = Selection { - try $0.on( - createArticleError: .init { .error(errorCode: (try? $0.errorCodes().first) ?? .unableToParse) }, - createArticleSuccess: .init { .saved(created: try $0.created()) } - ) - } - - let mutation = Selection.Mutation { - try $0.createArticle(input: input, selection: selection) - } - - let path = appEnvironment.graphqlPath - let headers = networker.defaultHeaders - - return Deferred { - Future { promise in - send(mutation, to: path, headers: headers) { result in - switch result { - case let .success(payload): - if let graphqlError = payload.errors { - promise(.failure(.unknown(description: graphqlError.first.debugDescription))) - } - - switch payload.data { - case .saved: - promise(.success(())) - case let .error(errorCode: errorCode): - switch errorCode { - case .unauthorized: - promise(.failure(.unauthorized)) - default: - promise(.failure(.unknown(description: errorCode.rawValue))) - } - } - case let .failure(error): - promise(.failure(SaveArticleError.make(from: error))) - } - } - } - } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() - } - - func saveArticlePublisher(articleURL: URL) -> AnyPublisher { - saveArticlePublisher(articleURLString: articleURL.absoluteString) - } - - func saveArticlePublisher(articleURLString: String) -> AnyPublisher { - enum MutationResult { - case saved(status: SaveArticleStatus) - case error(errorCode: Enums.CreateArticleSavingRequestErrorCode) - } - - let selection = Selection { - try $0.on( - createArticleSavingRequestError: .init { .error(errorCode: (try? $0.errorCodes().first) ?? .badData) }, - createArticleSavingRequestSuccess: .init { - .saved( - status: try $0.articleSavingRequest( - selection: .init { - SaveArticleStatus.make( - jobId: try $0.id(), - savingStatus: try $0.status() - ) - } - ) - ) - } - ) - } - - let mutation = Selection.Mutation { - try $0.createArticleSavingRequest( - input: InputObjects.CreateArticleSavingRequestInput(url: articleURLString), - selection: selection - ) - } - - let path = appEnvironment.graphqlPath - let headers = networker.defaultHeaders - - return Deferred { - Future { promise in - send(mutation, to: path, headers: headers) { result in - switch result { - case let .success(payload): - if let graphqlError = payload.errors { - promise(.failure(.unknown(description: graphqlError.first.debugDescription))) - } - - switch payload.data { - case let .saved(status): - promise(.success(status)) - case let .error(errorCode: errorCode): - switch errorCode { - case .unauthorized: - promise(.failure(.unauthorized)) - case .badData: - promise(.failure(.badData)) - } - } - case let .failure(error): - promise(.failure(SaveArticleError.make(from: error))) - } - } - } - } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() - } -} diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ValidateUsernameQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ValidateUsernameQuery.swift index 07137b3ac..4d427950f 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ValidateUsernameQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ValidateUsernameQuery.swift @@ -1,30 +1,29 @@ -import Combine import Foundation import Models import SwiftGraphQL public extension DataService { - func validateUsernamePublisher(username: String) -> AnyPublisher { + func validateUsernamePublisher(username: String) async throws { let query = Selection.Query { try $0.validateUsername(username: username) } let path = appEnvironment.graphqlPath - return Deferred { - Future { promise in - send(query, to: path) { result in - switch result { - case let .success(payload): - promise(payload.data ? .success(()) : .failure(.nameUnavailable)) - case let .failure(error): - promise(.failure(UsernameAvailabilityError.make(from: error))) + return try await withCheckedThrowingContinuation { continuation in + send(query, to: path) { result in + switch result { + case let .success(payload): + if payload.data { + continuation.resume() + } else { + continuation.resume(throwing: UsernameAvailabilityError.nameUnavailable) } + case let .failure(error): + continuation.resume(throwing: UsernameAvailabilityError.make(from: error)) } } } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() } }