diff --git a/Account/Sources/Account/FeedMetadataFile.swift b/Account/Sources/Account/FeedMetadataFile.swift index 1fa4569fe..d7e05a1a5 100644 --- a/Account/Sources/Account/FeedMetadataFile.swift +++ b/Account/Sources/Account/FeedMetadataFile.swift @@ -12,71 +12,69 @@ import Core @MainActor final class FeedMetadataFile { - private let log = OSLog(subsystem: Bundle.main.bundleIdentifier!, category: "feedMetadataFile") - private let fileURL: URL private let account: Account - - private var isDirty = false { - didSet { - queueSaveToDiskIfNeeded() - } - } - private let saveQueue = CoalescingQueue(name: "Save Queue", interval: 0.5) + private let dataFile: DataFile + private let logger = Logger(subsystem: Bundle.main.bundleIdentifier!, category: "FeedMetadataFile") init(filename: String, account: Account) { + self.fileURL = URL(fileURLWithPath: filename) self.account = account + self.dataFile = DataFile(fileURL: self.fileURL) + + self.dataFile.delegate = self } func markAsDirty() { - isDirty = true + + dataFile.markAsDirty() } func load() { + if let fileData = try? Data(contentsOf: fileURL) { let decoder = PropertyListDecoder() account.feedMetadata = (try? decoder.decode(Account.FeedMetadataDictionary.self, from: fileData)) ?? Account.FeedMetadataDictionary() } account.feedMetadata.values.forEach { $0.delegate = account } } - + + // Save immediately func save() { - guard !account.isDeleted else { return } + dataFile.save() + } +} + +extension FeedMetadataFile: DataFileDelegate { + + func data(for dataFile: DataFile) -> Data? { + + guard !account.isDeleted else { + return nil + } + let feedMetadata = metadataForOnlySubscribedToFeeds() let encoder = PropertyListEncoder() encoder.outputFormat = .binary - - do { - let data = try encoder.encode(feedMetadata) - try data.write(to: fileURL) - } catch let error as NSError { - os_log(.error, log: log, "Save to disk failed: %@.", error.localizedDescription) - } + return try? encoder.encode(feedMetadata) + } + + func dataFileWriteToDiskDidFail(for dataFile: DataFile, error: Error) { + + logger.error("FeedMetadataFile save to disk failed for \(self.fileURL): \(error.localizedDescription)") } - } private extension FeedMetadataFile { - func queueSaveToDiskIfNeeded() { - saveQueue.add(self, #selector(saveToDiskIfNeeded)) - } - - @objc func saveToDiskIfNeeded() { - if isDirty { - isDirty = false - save() - } - } - private func metadataForOnlySubscribedToFeeds() -> Account.FeedMetadataDictionary { + let feedIDs = account.idToFeedDictionary.keys return account.feedMetadata.filter { (feedID: String, metadata: FeedMetadata) -> Bool in return feedIDs.contains(metadata.feedID) } } - }