frenzy-ios/Reader/Widgets/WidgetHelper.swift

66 lines
2.4 KiB
Swift
Raw Normal View History

2022-06-20 15:32:58 +00:00
//
// WidgetHelper.swift
// Reader
//
// Created by Shadowfacts on 6/19/22.
//
import Foundation
import WidgetKit
import Persistence
2022-06-22 20:05:06 +00:00
import OSLog
private let logger = Logger(subsystem: "net.shadowfacts.Reader", category: "WidgetHelper")
private let signposter = OSSignposter(logger: logger)
2022-06-20 15:32:58 +00:00
struct WidgetHelper {
private init() {}
private static let maxDisplayableItems = 8
static func updateWidgetData(fervorController: FervorController) async {
// Accessing CoreData from the widget extension puts us over the memory limit, so we pre-generate all the data it needs and save it to disk
2022-06-22 20:05:06 +00:00
let context = fervorController.persistentContainer.backgroundContext
let prioritizedItems: [WidgetData.Item] = await context.perform {
2022-06-20 15:32:58 +00:00
let req = Item.fetchRequest()
req.sortDescriptors = [NSSortDescriptor(key: "published", ascending: false)]
req.fetchLimit = 32
req.predicate = NSPredicate(format: "read = NO")
let state = signposter.beginInterval("fetch")
2022-06-22 20:05:06 +00:00
var items = (try? context.fetch(req)) ?? []
signposter.endInterval("fetch", state)
2022-06-20 15:32:58 +00:00
var prioritizedItems: [Item] = []
while prioritizedItems.count < maxDisplayableItems {
let firstFromUnseenFeedIdx = items.firstIndex { item in
prioritizedItems.allSatisfy { existing in
existing.feed != item.feed
}
}
if let firstFromUnseenFeedIdx {
prioritizedItems.append(items.remove(at: firstFromUnseenFeedIdx))
} else if let item = items.first {
prioritizedItems.append(item)
items.removeFirst()
} else {
break
}
}
return prioritizedItems.map {
WidgetData.Item(id: $0.id!, feedTitle: $0.feed?.title, title: $0.title, published: $0.published)
}
}
if let item = prioritizedItems.first {
logger.info("Saving widget data with first item: '\(item.title ?? "<untitled>", privacy: .public)'")
}
2022-09-08 02:57:48 +00:00
2022-06-20 15:32:58 +00:00
WidgetData(recentItems: prioritizedItems).save(account: fervorController.account!)
WidgetCenter.shared.reloadAllTimelines()
}
}