mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
read/write article content using coredata
This commit is contained in:
parent
a879a68ad8
commit
00639011d8
6 changed files with 32 additions and 109 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -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?) {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue