This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
final class WidgetPlantProvider { | |
private var cancellables = [AnyCancellable]() | |
private let plantContainer: PlantContainer // NSPersistentContainer subclass | |
init(plantContainer: PlantContainer, notificationCenter: NotificationCenter = .default) { | |
self.plantContainer = plantContainer | |
let notificationCancellable = notificationCenter.publisher(for: .NSManagedObjectContextDidSave, object: plantContainer.viewContext).sink { [weak self] _ in | |
self?.reloadData() | |
} | |
cancellables.append(notificationCancellable) | |
} | |
// Called when NSPersistentContainer is first loaded | |
func reloadData() { | |
plantContainer.performBackgroundTask { context in | |
let descriptors = [NSSortDescriptor(keyPath: \Plant.nextWateringDate, ascending: true)] | |
// fetchDictionaries is convenience method which creates and executes NSFetchRequest<NSDictionary> and sets resultType = .dictionaryResultType | |
let dictionaries = Plant.fetchDictionaries(context, sortDescriptors: descriptors, fetchLimit: 3) as! [[String: Any]] | |
// NSDate -> double conversion | |
let converted = dictionaries.map { (plantDictionary) -> [String: Any] in | |
return plantDictionary.mapValues { (value) -> Any in | |
guard let date = value as? Date else { return value } | |
return date.timeIntervalSince1970 | |
} | |
} | |
do { | |
let needsFileReload: Bool = { | |
guard let storedData = try? Data(contentsOf: Self.sharedDataFileURL) else { return true } | |
guard let storedDictionaries = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(storedData) as? [NSDictionary] else { return true } | |
return storedDictionaries != converted as [NSDictionary] | |
}() | |
if !needsFileReload { | |
os_log(.debug, log: .widget, "Plants already up to date for widget") | |
return | |
} | |
let data = try NSKeyedArchiver.archivedData(withRootObject: converted, requiringSecureCoding: true) | |
try data.write(to: Self.sharedDataFileURL) | |
os_log(.debug, log: .widget, "Reloading widget because plants changed") | |
WidgetCenter.shared.reloadAllTimelines() | |
} | |
catch { | |
os_log(.debug, log: .widget, "Failed updating plants for widget with error %s", error.localizedDescription) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment