mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
convert save page publisher to async
This commit is contained in:
parent
6f35740272
commit
822a38a863
2 changed files with 79 additions and 60 deletions
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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<Void, SaveArticleError> {
|
||||
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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue