From 00639011d898393cd3f8e9435d477f74507e4f92 Mon Sep 17 00:00:00 2001 From: Satindar Dhillon Date: Sat, 16 Apr 2022 09:12:10 -0700 Subject: [PATCH] read/write article content using coredata --- .../Views/WebReader/WebReaderViewModel.swift | 1 - .../CoreDataModel.xcdatamodel/contents | 2 +- .../OmnivoreKit/Sources/Models/FeedItem.swift | 63 ------------------- .../Sources/Models/FeedItemLabel.swift | 31 --------- .../Services/DataService/DataService.swift | 24 +++---- .../Queries/ArticleContentQuery.swift | 20 +++++- 6 files changed, 32 insertions(+), 109 deletions(-) diff --git a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift index 2afceda35..081311164 100644 --- a/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift +++ b/apple/OmnivoreKit/Sources/App/Views/WebReader/WebReaderViewModel.swift @@ -39,7 +39,6 @@ final class WebReaderViewModel: ObservableObject { }, receiveValue: { [weak self] articleContent in self?.articleContent = articleContent - dataService.pageCache.setObject(CachedPageContent(slug, articleContent), forKey: NSString(string: slug)) } ) .store(in: &subscriptions) 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 605103808..31fc245a2 100644 --- a/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents +++ b/apple/OmnivoreKit/Sources/Models/CoreData/CoreDataModel.xcdatamodeld/CoreDataModel.xcdatamodel/contents @@ -32,7 +32,7 @@ - + \ No newline at end of file diff --git a/apple/OmnivoreKit/Sources/Models/FeedItem.swift b/apple/OmnivoreKit/Sources/Models/FeedItem.swift index 3e95f54c8..3a2b3ea83 100644 --- a/apple/OmnivoreKit/Sources/Models/FeedItem.swift +++ b/apple/OmnivoreKit/Sources/Models/FeedItem.swift @@ -1,4 +1,3 @@ -// import CoreData import Foundation public struct HomeFeedData { @@ -11,33 +10,6 @@ public struct HomeFeedData { } } -// public class FeedItemManagedObject: NSManagedObject { -// static let entityName = "FeedItemManagedObject" -// -// @nonobjc public class func fetchRequest() -> NSFetchRequest { -// NSFetchRequest(entityName: entityName) -// } -// -// @NSManaged public var id: String -// @NSManaged public var title: String -// @NSManaged public var createdAt: Date -// @NSManaged public var savedAt: Date -// @NSManaged public var readingProgress: Double -// @NSManaged public var readingProgressAnchor: Int -// @NSManaged public var imageURLString: String? -// @NSManaged public var onDeviceImageURLString: String? -// @NSManaged public var documentDirectoryPath: String? -// @NSManaged public var pageURLString: String -// @NSManaged public var descriptionText: String? -// @NSManaged public var publisherURLString: String? -// @NSManaged public var author: String? -// @NSManaged public var publishDate: Date? -// @NSManaged public var slug: String -// @NSManaged public var isArchived: Bool -// @NSManaged public var contentReader: String? -// @NSManaged public var labels: Set -// } - public struct FeedItem: Identifiable, Hashable { public let id: String public let title: String @@ -98,41 +70,6 @@ public struct FeedItem: Identifiable, Hashable { self.labels = labels } -// func toManagedObject(inContext context: NSManagedObjectContext) -> FeedItemManagedObject? { -// let entityName = FeedItemManagedObject.entityName -// guard let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: context) else { -// print("Failed to create \(entityName)") -// return nil -// } -// -// let object = FeedItemManagedObject(entity: entityDescription, insertInto: context) -// object.id = id -// object.title = title -// object.createdAt = createdAt -// object.savedAt = savedAt -// object.readingProgress = readingProgress -// object.readingProgressAnchor = readingProgressAnchor -// object.imageURLString = imageURLString -// object.onDeviceImageURLString = onDeviceImageURLString -// object.documentDirectoryPath = documentDirectoryPath -// object.pageURLString = pageURLString -// object.descriptionText = descriptionText -// object.publisherURLString = publisherURLString -// object.author = author -// object.publishDate = publishDate -// object.slug = slug -// object.isArchived = isArchived -// object.contentReader = contentReader -// -// for label in labels { -// if let managedLabel = label.toManagedObject(inContext: context) { -// object.labels.insert(managedLabel) -// } -// } -// -// return object -// } - public static func fromJsonArticle(linkData: Data) -> FeedItem? { try? JSONDecoder().decode(JSONArticle.self, from: linkData).feedItem } diff --git a/apple/OmnivoreKit/Sources/Models/FeedItemLabel.swift b/apple/OmnivoreKit/Sources/Models/FeedItemLabel.swift index b37af81a9..eeed689b7 100644 --- a/apple/OmnivoreKit/Sources/Models/FeedItemLabel.swift +++ b/apple/OmnivoreKit/Sources/Models/FeedItemLabel.swift @@ -1,4 +1,3 @@ -// import CoreData import Foundation public struct FeedItemLabel: Decodable, Hashable { @@ -21,34 +20,4 @@ public struct FeedItemLabel: Decodable, Hashable { self.createdAt = createdAt self.labelDescription = labelDescription } - -// func toManagedObject(inContext context: NSManagedObjectContext) -> FeedItemLabelManagedObject? { -// let entityName = FeedItemLabelManagedObject.entityName -// guard let entityDescription = NSEntityDescription.entity(forEntityName: entityName, in: context) else { -// print("Failed to create \(entityName)") -// return nil -// } -// -// let object = FeedItemLabelManagedObject(entity: entityDescription, insertInto: context) -// object.id = id -// object.name = name -// object.color = color -// object.createdAt = createdAt -// object.labelDescription = labelDescription -// return object -// } } - -// public class FeedItemLabelManagedObject: NSManagedObject { -// static let entityName = "FeedItemLabelManagedObject" -// -// @nonobjc public class func fetchRequest() -> NSFetchRequest { -// NSFetchRequest(entityName: entityName) -// } -// -// @NSManaged public var id: String -// @NSManaged public var name: String -// @NSManaged public var color: String -// @NSManaged public var createdAt: Date? -// @NSManaged public var labelDescription: String? -// } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift index 846e337c8..b0f4e7e41 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/DataService.swift @@ -1,4 +1,5 @@ import Combine +import CoreData import Foundation import Models @@ -10,9 +11,6 @@ public final class DataService: ObservableObject { public internal(set) var currentViewer: Viewer? let networker: Networker - public let pageCache = NSCache() - let pageCacheQueue = DispatchQueue.global(qos: .background) - let highlightsCache = NSCache() let highlightsCacheQueue = DispatchQueue(label: "app.omnivore.highlights.cache.queue", attributes: .concurrent) @@ -53,21 +51,23 @@ public extension DataService { let slug = item.slug articleContentPublisher(username: viewer.username, slug: slug).sink( receiveCompletion: { _ in }, - receiveValue: { [weak self] articleContent in - self?.pageCache.setObject(CachedPageContent(slug, articleContent), forKey: NSString(string: slug)) - } + receiveValue: { _ in } ) .store(in: &subscriptions) } } func pageFromCache(slug: String) -> ArticleContent? { - pageCache.object(forKey: NSString(string: slug))?.value - } - - func invalidateCachedPage(slug: String?) { - if let slug = slug { - pageCache.removeObject(forKey: NSString(string: slug)) + let fetchRequest: NSFetchRequest = PersistedArticleContent.fetchRequest() + fetchRequest.predicate = NSPredicate( + format: "slug = %@", slug + ) + if let htmlContent = try? persistentContainer.viewContext.fetch(fetchRequest).first?.htmlContent { + return ArticleContent(htmlContent: htmlContent, highlights: []) + } else { + return nil } } + + func invalidateCachedPage(slug _: String?) {} } diff --git a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift index 8822a0d98..3218215d8 100644 --- a/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift +++ b/apple/OmnivoreKit/Sources/Services/DataService/Queries/ArticleContentQuery.swift @@ -37,11 +37,13 @@ public extension DataService { return Deferred { Future { promise in - send(query, to: path, headers: headers) { result in + send(query, to: path, headers: headers) { [weak self] result in switch result { case let .success(payload): switch payload.data { case let .success(result: result): + // store result in core data + self?.persistArticleContent(htmlContent: result.htmlContent, slug: slug) promise(.success(result)) case .error: promise(.failure(.unknown)) @@ -56,3 +58,19 @@ public extension DataService { .eraseToAnyPublisher() } } + +extension DataService { + func persistArticleContent(htmlContent: String, slug: String) { + let persistedArticleContent = PersistedArticleContent(context: persistentContainer.viewContext) + persistedArticleContent.htmlContent = htmlContent + persistedArticleContent.slug = slug + + do { + try persistentContainer.viewContext.save() + print("PersistedArticleContent saved succesfully") + } catch { + persistentContainer.viewContext.rollback() + print("Failed to save PersistedArticleContent: \(error)") + } + } +}