diff --git a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift
index 4240b9509..d9b3c5e48 100644
--- a/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift
+++ b/apple/OmnivoreKit/Sources/App/PDFSupport/PDFViewerViewModel.swift
@@ -41,7 +41,7 @@ public final class PDFViewerViewModel: ObservableObject {
for highlight in fetchedHighlights {
resultSet[highlight.id] = highlight
}
- for highlightId in services.dataService.fetchRemovedHighlightIds(pdfID: feedItem.id) {
+ for highlightId in services.dataService.deletedHighlightsIDs {
resultSet.removeValue(forKey: highlightId)
}
return Array(resultSet.values)
@@ -164,6 +164,6 @@ public final class PDFViewerViewModel: ObservableObject {
}
private func removeLocalHighlights(highlightIds: [String]) {
- services.dataService.removeHighlights(pdfID: feedItem.id, highlightIds: highlightIds)
+ services.dataService.removeHighlights(highlightIds: highlightIds)
}
}
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 8002ea47e..449b5cd29 100644
--- a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents
+++ b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents
@@ -3,6 +3,11 @@
+
+
+
+
+
@@ -22,6 +27,11 @@
+
+
+
+
+
@@ -29,23 +39,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/apple/OmnivoreKit/Sources/Models/Highlight.swift b/apple/OmnivoreKit/Sources/Models/Highlight.swift
index 477c33352..a7d079125 100644
--- a/apple/OmnivoreKit/Sources/Models/Highlight.swift
+++ b/apple/OmnivoreKit/Sources/Models/Highlight.swift
@@ -1,3 +1,4 @@
+import CoreData
import Foundation
public struct Highlight: Identifiable, Hashable, Codable {
@@ -35,4 +36,36 @@ public struct Highlight: Identifiable, Hashable, Codable {
self.updatedAt = updatedAt
self.createdByMe = createdByMe
}
+
+ public func toManagedObject(context: NSManagedObjectContext, associatedItemID: String) -> PersistedHighlight {
+ let persistedHighlight = PersistedHighlight(context: context)
+ persistedHighlight.associatedItemId = associatedItemID
+ persistedHighlight.markedForDeletion = false
+ persistedHighlight.id = id
+ persistedHighlight.shortId = shortId
+ persistedHighlight.quote = quote
+ persistedHighlight.prefix = prefix
+ persistedHighlight.suffix = suffix
+ persistedHighlight.patch = patch
+ persistedHighlight.annotation = annotation
+ persistedHighlight.createdAt = createdAt
+ persistedHighlight.updatedAt = updatedAt
+ persistedHighlight.createdByMe = createdByMe
+ return persistedHighlight
+ }
+
+ public static func make(from persistedHighlight: PersistedHighlight) -> Highlight {
+ Highlight(
+ id: persistedHighlight.id ?? "",
+ shortId: persistedHighlight.shortId ?? "",
+ quote: persistedHighlight.quote ?? "",
+ prefix: persistedHighlight.prefix,
+ suffix: persistedHighlight.suffix,
+ patch: persistedHighlight.patch ?? "",
+ annotation: persistedHighlight.annotation,
+ createdByMe: persistedHighlight.createdByMe,
+ createdAt: persistedHighlight.createdAt,
+ updatedAt: persistedHighlight.updatedAt
+ )
+ }
}
diff --git a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift
index b0f4e7e41..83fa20999 100644
--- a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift
+++ b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift
@@ -11,11 +11,9 @@ public final class DataService: ObservableObject {
public internal(set) var currentViewer: Viewer?
let networker: Networker
- let highlightsCache = NSCache()
- let highlightsCacheQueue = DispatchQueue(label: "app.omnivore.highlights.cache.queue", attributes: .concurrent)
-
let persistentContainer: PersistentContainer
var subscriptions = Set()
+ public var deletedHighlightsIDs = Set()
public init(appEnvironment: AppEnvironment, networker: Networker) {
self.appEnvironment = appEnvironment
@@ -30,7 +28,21 @@ public final class DataService: ObservableObject {
}
public func clearHighlights() {
- highlightsCache.removeAllObjects()
+ deletedHighlightsIDs.removeAll()
+
+ let fetchRequest: NSFetchRequest = PersistedHighlight.fetchRequest()
+
+ let highlights = (try? persistentContainer.viewContext.fetch(fetchRequest)) ?? []
+
+ for highlight in highlights {
+ persistentContainer.viewContext.delete(highlight)
+ }
+
+ do {
+ try persistentContainer.viewContext.save()
+ } catch {
+ print("failed to delete objects")
+ }
}
public func switchAppEnvironment(appEnvironment: AppEnvironment) {
diff --git a/apple/OmnivoreKit/Sources/Services/Persistence/PersistableModels/CachedPDFHighlights.swift b/apple/OmnivoreKit/Sources/Services/Persistence/PersistableModels/CachedPDFHighlights.swift
index 35ece139b..c9a225c11 100644
--- a/apple/OmnivoreKit/Sources/Services/Persistence/PersistableModels/CachedPDFHighlights.swift
+++ b/apple/OmnivoreKit/Sources/Services/Persistence/PersistableModels/CachedPDFHighlights.swift
@@ -1,57 +1,53 @@
import Combine
+import CoreData
import Foundation
import Models
-final class CachedPDFHighlights {
- init(pdfID: String, highlights: [Highlight], removedHighlightIDs: [String]) {
- self.pdfID = pdfID
- self.highlights = highlights
- self.removedHighlightIDs = removedHighlightIDs
- }
-
- let pdfID: String
- var highlights: [Highlight]
- var removedHighlightIDs: [String]
-}
-
public extension DataService {
func cachedHighlights(pdfID: String) -> [Highlight] {
- fetchCachedHighlights(pdfID: pdfID as NSString)?.highlights ?? []
- }
+ let fetchRequest: NSFetchRequest = PersistedHighlight.fetchRequest()
+ fetchRequest.predicate = NSPredicate(
+ format: "associatedItemId = %@ AND markedForDeletion = %@", pdfID, false
+ )
- func fetchRemovedHighlightIds(pdfID: String) -> [String] {
- fetchCachedHighlights(pdfID: pdfID as NSString)?.removedHighlightIDs ?? []
+ let highlights = (try? persistentContainer.viewContext.fetch(fetchRequest)) ?? []
+ return highlights.map { Highlight.make(from: $0) }
}
func persistHighlight(pdfID: String, highlight: Highlight) {
- let cachedHighlights =
- fetchCachedHighlights(pdfID: pdfID as NSString)
- ?? CachedPDFHighlights(pdfID: pdfID, highlights: [], removedHighlightIDs: [])
+ _ = highlight.toManagedObject(
+ context: persistentContainer.viewContext,
+ associatedItemID: pdfID
+ )
- cachedHighlights.highlights.append(highlight)
- insertCachedHighlights(highlights: cachedHighlights, pdfID: pdfID as NSString)
- }
-
- func removeHighlights(pdfID: String, highlightIds: [String]) {
- let cachedHighlights =
- fetchCachedHighlights(pdfID: pdfID as NSString)
- ?? CachedPDFHighlights(pdfID: pdfID, highlights: [], removedHighlightIDs: [])
-
- cachedHighlights.removedHighlightIDs.append(contentsOf: highlightIds)
- insertCachedHighlights(highlights: cachedHighlights, pdfID: pdfID as NSString)
- }
-
- private func fetchCachedHighlights(pdfID: NSString) -> CachedPDFHighlights? {
- var cachedHighlights: CachedPDFHighlights?
- highlightsCacheQueue.sync {
- cachedHighlights = highlightsCache.object(forKey: pdfID as NSString)
+ do {
+ try persistentContainer.viewContext.save()
+ print("PersistedHighlight saved succesfully")
+ } catch {
+ persistentContainer.viewContext.rollback()
+ print("Failed to save PersistedHighlight: \(error)")
}
- return cachedHighlights
}
- private func insertCachedHighlights(highlights: CachedPDFHighlights, pdfID: NSString) {
- highlightsCacheQueue.async(flags: .barrier) {
- self.highlightsCache.setObject(highlights, forKey: pdfID as AnyObject)
+ func removeHighlights(highlightIds: [String]) {
+ for highlightID in highlightIds {
+ deletedHighlightsIDs.insert(highlightID)
+ }
+
+ let fetchRequest: NSFetchRequest = PersistedHighlight.fetchRequest()
+ fetchRequest.predicate = NSPredicate(format: "id IN %@", highlightIds)
+ guard let highlights = try? persistentContainer.viewContext.fetch(fetchRequest) else { return }
+
+ for highlight in highlights {
+ highlight.markedForDeletion = true
+ }
+
+ do {
+ try persistentContainer.viewContext.save()
+ print("PersistedHighlight(s) updated succesfully")
+ } catch {
+ persistentContainer.viewContext.rollback()
+ print("Failed to update PersistedHighlight(s): \(error)")
}
}
}