Last active
August 30, 2020 00:31
-
-
Save laevandus/c268d222253c184f7b8e73d2a753e512 to your computer and use it in GitHub Desktop.
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