mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Prefetch page content on iOS
This commit is contained in:
parent
1c4ca835d3
commit
a1feffaf03
4 changed files with 53 additions and 0 deletions
|
|
@ -76,6 +76,9 @@ final class HomeFeedViewModel: ObservableObject {
|
|||
if thisSearchIdx > 0, thisSearchIdx <= self?.receivedIdx ?? 0 {
|
||||
return
|
||||
}
|
||||
|
||||
dataService.prefetchPages(items: result.items)
|
||||
|
||||
self?.items = isRefresh ? result.items : (self?.items ?? []) + result.items
|
||||
self?.isLoading = false
|
||||
self?.receivedIdx = thisSearchIdx
|
||||
|
|
|
|||
|
|
@ -28,6 +28,15 @@ final class WebReaderViewModel: ObservableObject {
|
|||
|
||||
guard let viewer = dataService.currentViewer else { return }
|
||||
|
||||
if let content = dataService.pageCache.object(forKey: NSString(string: slug)) {
|
||||
print("RETRIEVED FORM CACHE", slug)
|
||||
isLoading = false
|
||||
articleContent = content.value
|
||||
return
|
||||
} else {
|
||||
print("MISSED CACHE", slug)
|
||||
}
|
||||
|
||||
dataService.articleContentPublisher(username: viewer.username, slug: slug).sink(
|
||||
receiveCompletion: { [weak self] completion in
|
||||
guard case .failure = completion else { return }
|
||||
|
|
@ -35,6 +44,7 @@ final class WebReaderViewModel: ObservableObject {
|
|||
},
|
||||
receiveValue: { [weak self] articleContent in
|
||||
self?.articleContent = articleContent
|
||||
dataService.pageCache.setObject(CachedPageContent(articleContent), forKey: NSString(string: slug))
|
||||
}
|
||||
)
|
||||
.store(in: &subscriptions)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,13 @@
|
|||
import Foundation
|
||||
|
||||
public class CachedPageContent: NSObject {
|
||||
public let value: ArticleContent
|
||||
|
||||
public init(_ content: ArticleContent) {
|
||||
self.value = content
|
||||
}
|
||||
}
|
||||
|
||||
public struct ArticleContent {
|
||||
public let htmlContent: String
|
||||
public let highlights: [Highlight]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,13 @@
|
|||
import Combine
|
||||
import Foundation
|
||||
import Models
|
||||
|
||||
public class CacheManager: NSObject, NSCacheDelegate {
|
||||
public func cache(_: NSCache<AnyObject, AnyObject>, willEvictObject obj: Any) {
|
||||
print("evicting object", obj)
|
||||
}
|
||||
}
|
||||
|
||||
public final class DataService: ObservableObject {
|
||||
public static var registerIntercomUser: ((String) -> Void)?
|
||||
public static var showIntercomMessenger: (() -> Void)?
|
||||
|
|
@ -9,12 +16,37 @@ 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)
|
||||
|
||||
let cacheManager: CacheManager
|
||||
var subscriptions = Set<AnyCancellable>()
|
||||
|
||||
public init(appEnvironment: AppEnvironment, networker: Networker) {
|
||||
self.appEnvironment = appEnvironment
|
||||
self.networker = networker
|
||||
self.cacheManager = CacheManager()
|
||||
pageCache.delegate = cacheManager
|
||||
}
|
||||
|
||||
public func prefetchPages(items: [FeedItem]) {
|
||||
print("prefetching items", items, "cost limit", pageCache.countLimit)
|
||||
|
||||
guard let viewer = currentViewer else { return }
|
||||
|
||||
for item in items {
|
||||
let slug = item.slug
|
||||
articleContentPublisher(username: viewer.username, slug: slug).sink(
|
||||
receiveCompletion: { _ in },
|
||||
receiveValue: { [weak self] articleContent in
|
||||
self?.pageCache.setObject(CachedPageContent(articleContent), forKey: NSString(string: slug))
|
||||
}
|
||||
)
|
||||
.store(in: &subscriptions)
|
||||
}
|
||||
}
|
||||
|
||||
public func clearHighlights() {
|
||||
|
|
|
|||
Loading…
Reference in a new issue