read/write article content using coredata

This commit is contained in:
Satindar Dhillon 2022-04-16 09:12:10 -07:00
parent a879a68ad8
commit 00639011d8
6 changed files with 32 additions and 109 deletions

View file

@ -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)

View file

@ -32,7 +32,7 @@
</entity>
<elements>
<element name="PersistedFeedItemLabel" positionX="-36" positionY="18" width="128" height="104"/>
<element name="PersistedFeedItem" positionX="-18" positionY="63" width="128" height="14"/>
<element name="PersistedFeedItem" positionX="-18" positionY="63" width="128" height="284"/>
<element name="PersistedArticleContent" positionX="9" positionY="108" width="128" height="59"/>
</elements>
</model>

View file

@ -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<FeedItemManagedObject> {
// NSFetchRequest<FeedItemManagedObject>(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<FeedItemLabelManagedObject>
// }
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
}

View file

@ -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<FeedItemLabelManagedObject> {
// NSFetchRequest<FeedItemLabelManagedObject>(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?
// }

View file

@ -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<NSString, CachedPageContent>()
let pageCacheQueue = DispatchQueue.global(qos: .background)
let highlightsCache = NSCache<AnyObject, CachedPDFHighlights>()
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<Models.PersistedArticleContent> = 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?) {}
}

View file

@ -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)")
}
}
}