From 611b237e1703cf365caf28019b11657dd99787bc Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 7 Jun 2022 12:00:22 -0700 Subject: [PATCH] Handle save operations completing in the background while opening itemIDs --- .../Share/ExtensionSaveService.swift | 6 +-- .../WebReader/WebReaderLoadingContainer.swift | 40 ++++++++++++++----- .../CoreDataModel.xcdatamodel/contents | 3 +- .../Services/DataService/DataService.swift | 1 + 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ExtensionSaveService.swift b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ExtensionSaveService.swift index 1350d936a..f40b8a61c 100644 --- a/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ExtensionSaveService.swift +++ b/apple/OmnivoreKit/Sources/App/AppExtensions/Share/ExtensionSaveService.swift @@ -168,11 +168,11 @@ class ExtensionSaveService { switch pageScrapePayload.contentType { case .none: - requestId = try await services.dataService.syncUrl(id: requestId, url: pageScrapePayload.url) + requestId = try await services.dataService.createPageFromUrl(id: requestId, url: pageScrapePayload.url) case let .pdf(localUrl): - try await services.dataService.syncPdf(id: requestId, localPdfURL: localUrl, url: pageScrapePayload.url) + try await services.dataService.createPageFromPdf(id: requestId, localPdfURL: localUrl, url: pageScrapePayload.url) case let .html(html, title, _): - requestId = try await services.dataService.syncPage( + requestId = try await services.dataService.createPage( id: requestId, originalHtml: html, title: title, diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift index 756a9b57c..c09fc7816 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderLoadingContainer.swift @@ -25,19 +25,15 @@ import Utils guard let username = username else { return } - let fetchRequest: NSFetchRequest = LinkedItem.fetchRequest() - fetchRequest.predicate = NSPredicate(format: "id == %@", requestID) - if let existingItem = try? dataService.viewContext.fetch(fetchRequest).first, - existingItem.serverSyncStatus == ServerSyncStatus.isNSync.rawValue - { - print("USING EXISTING ITEM", existingItem.serverSyncStatus) + let existing = existingItemOrItemId(dataService: dataService, requestID: requestID) + if let existingItem = existing.existingItem { item = existingItem return } // If the page was locally created, make sure they are synced before we pull content - await dataService.syncUnsyncedArticleContent(itemID: requestID) - await fetchLinkedItem(dataService: dataService, requestID: requestID, username: username) + await dataService.syncUnsyncedArticleContent(itemID: existing.itemID) + await fetchLinkedItem(dataService: dataService, requestID: existing.itemID, username: username) } private func fetchLinkedItem( @@ -64,9 +60,16 @@ import Utils do { let retryDelayInNanoSeconds = UInt64(requestCount * 2 * 1_000_000_000) try await Task.sleep(nanoseconds: retryDelayInNanoSeconds) + + let existing = existingItemOrItemId(dataService: dataService, requestID: requestID) + if let existingItem = existing.existingItem { + item = existingItem + return + } + await fetchLinkedItem( dataService: dataService, - requestID: requestID, + requestID: existing.itemID, username: username, requestCount: requestCount + 1 ) @@ -75,6 +78,25 @@ import Utils } } + private func existingItemOrItemId(dataService: DataService, requestID: String) -> (existingItem: LinkedItem?, itemID: String) { + let fetchRequest: NSFetchRequest = LinkedItem.fetchRequest() + fetchRequest.predicate = NSPredicate(format: "createdId == %@ OR id == %@", requestID, requestID) + if let existingItem = try? dataService.viewContext.fetch(fetchRequest).first { + // If the existing item is synced, we can use it + if let itemID = existingItem.id, existingItem.serverSyncStatus == ServerSyncStatus.isNSync.rawValue { + item = existingItem + return (existingItem: item, itemID: itemID) + } + + // If the existing item is not synced, we might have an updated request id + if let existingID = existingItem.id { + return (existingItem: nil, itemID: existingID) + } + } + + return (existingItem: nil, itemID: requestID) + } + func trackReadEvent() { guard let item = item else { return } diff --git a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents index 63bdc0cd9..3316d15b9 100644 --- a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents +++ b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents @@ -24,6 +24,7 @@ + @@ -89,7 +90,7 @@ - + diff --git a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift index 123faa838..7e12640b0 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift @@ -121,6 +121,7 @@ public final class DataService: ObservableObject { let existingItem = try? self.backgroundContext.fetch(fetchRequest).first let linkedItem = existingItem ?? LinkedItem(entity: LinkedItem.entity(), insertInto: self.backgroundContext) + linkedItem.createdId = requestId linkedItem.id = existingItem?.unwrappedID ?? requestId linkedItem.title = normalizedURL linkedItem.pageURLString = normalizedURL