diff --git a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift index e52e92eda..74aaba17d 100644 --- a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift +++ b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ShareExtensionScene.swift @@ -45,49 +45,71 @@ final class ShareExtensionViewModel: ObservableObject { backgroundTask = UIApplication.shared.beginBackgroundTask(withName: requestID) PageScraper.scrape(extensionContext: extensionContext) { [weak self] result in + guard let self = self else { return } switch result { case let .success(payload): - self?.persist(pageScrapePayload: payload, requestId: self?.requestID ?? "") + Task { + await self.persist(pageScrapePayload: payload, requestId: self.requestID) + } case let .failure(error): - if let backgroundTask = self?.backgroundTask { + if let backgroundTask = self.backgroundTask { UIApplication.shared.endBackgroundTask(backgroundTask) } - self?.debugText = error.message + self.debugText = error.message } } } - private func persist(pageScrapePayload: PageScrapePayload, requestId: String) { + private func persist(pageScrapePayload: PageScrapePayload, requestId: String) async { let services = Services() - Task { - do { - // Save locally, then attempt to sync to the server - let item = try await services.dataService.persistPageScrapePayload(pageScrapePayload, requestId: requestId) - // TODO: need to update this on the main thread and handle the result == false case here - if item != nil { - self.status = .saved - } else { - self.status = .failed(error: SaveArticleError.unknown(description: "Unable to save page")) - return - } + // Save locally first + let linkedItem = try? await services.dataService.persistPageScrapePayload(pageScrapePayload, requestId: requestId) - // force a server sync - if let item = item { - let syncResult = services.dataService.syncLocalCreatedLinkedItem(item: item) - print("RESULT", syncResult) - } -// self.status = .synced -// } else { -// self.status = .syncFailed(error: SaveArticleError.unknown(description: "Unable to sync page")) -// } - - } catch { - print("ERROR SAVING PAGE", error) - } + if let linkedItem = linkedItem { + // Sync with server now that we saved the item locally + services.dataService.syncLocalCreatedLinkedItem(item: linkedItem) + updateStatus(newStatus: .saved) + } else { + updateStatus(newStatus: .failed(error: SaveArticleError.unknown(description: "Unable to save page"))) } - // First persist to Core Data - // services.dataService.persist(jsonArticle: article) + } + + private func updateStatus(newStatus: ShareExtensionStatus) { + DispatchQueue.main.async { + self.status = newStatus + } + } +} + +// Task { +// do { +// // Save locally, then attempt to sync to the server +// let item = try await services.dataService.persistPageScrapePayload(pageScrapePayload, requestId: requestId) +// // TODO: need to update this on the main thread and handle the result == false case here +// if item != nil { +// self.status = .saved +// } else { +// self.status = .failed(error: SaveArticleError.unknown(description: "Unable to save page")) +// return +// } +// +// // force a server sync +// if let item = item { +// let syncResult = services.dataService.syncLocalCreatedLinkedItem(item: item) +// print("RESULT", syncResult) +// } +//// self.status = .synced +//// } else { +//// self.status = .syncFailed(error: SaveArticleError.unknown(description: "Unable to sync page")) +//// } +// +// } catch { +// print("ERROR SAVING PAGE", error) +// } +// } +// // First persist to Core Data +// // services.dataService.persist(jsonArticle: article) // // guard services.authenticator.hasValidAuthToken else { @@ -137,8 +159,8 @@ final class ShareExtensionViewModel: ObservableObject { // } // } // } - } -} +// } +// } struct ShareExtensionView: View { let extensionContext: NSExtensionContext? diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePage.swift b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePage.swift index 9f34c2268..a6241f260 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePage.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Mutations/SavePage.swift @@ -1,11 +1,9 @@ -import Combine import Foundation import Models import SwiftGraphQL public extension DataService { - // swiftlint:disable:next line_length - func savePagePublisher(pageScrapePayload: PageScrapePayload, html: String, title: String?, requestId: String) -> AnyPublisher { + func savePage(pageScrapePayload: PageScrapePayload, html: String, title: String?, requestId: String) async throws { enum MutationResult { case saved(requestId: String, url: String) case error(errorCode: Enums.SaveErrorCode) @@ -35,38 +33,37 @@ public extension DataService { 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(SaveError.make(from: error))) + return try await withCheckedThrowingContinuation { continuation in + send(mutation, to: path, headers: headers) { result in + switch result { + case let .success(payload): + if let graphqlError = payload.errors { + continuation.resume( + throwing: SaveArticleError.unknown(description: graphqlError.first.debugDescription) + ) + return } + + switch payload.data { + case .saved: + continuation.resume() + case let .error(errorCode: errorCode): + switch errorCode { + case .unauthorized: + continuation.resume(throwing: SaveArticleError.unauthorized) + default: + continuation.resume(throwing: SaveArticleError.unknown(description: errorCode.rawValue)) + } + } + case let .failure(error): + continuation.resume(throwing: SaveArticleError.make(from: error)) } } } - .receive(on: DispatchQueue.main) - .eraseToAnyPublisher() } } -private extension SaveError { +private extension SaveArticleError { static func make(from httpError: HttpError) -> SaveArticleError { switch httpError { case .network, .timeout: