Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@laevandus
Last active August 30, 2020 00:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save laevandus/03c6314fca8c64d8a824918c97a78e96 to your computer and use it in GitHub Desktop.
Save laevandus/03c6314fca8c64d8a824918c97a78e96 to your computer and use it in GitHub Desktop.
struct Provider: TimelineProvider {
// …
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
let plants = loadPlants()
let entry = PlantEntry(date: Date(), plants: plants)
let timeline = Timeline(entries: [entry], policy: .atEnd)
completion(timeline)
}
private func loadPlants() -> [PlantRepresentation] {
do {
let data = try Data(contentsOf: Self.sharedDataFileURL)
let plantDictionaries = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data) as? [[String: Any]]
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .secondsSince1970
return plantDictionaries?.compactMap({ PlantRepresentation(dictionary: $0, decoder: decoder) }) ?? []
}
catch {
print(error.localizedDescription)
return []
}
}
private static var sharedDataFileURL: URL {
let identifier = "group.com.company.appname.widget"
if let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: identifier) {
return url.appendingPathComponent("Plants.plist")
}
else {
preconditionFailure("Expected a valid app group container")
}
}
}
// DictionaryDecodable: https://augmentedcode.io/2019/05/12/storing-struct-in-userdefaults/
struct PlantRepresentation: Identifiable, Decodable, DictionaryDecodable {
let id: String
let name: String
let lastWateringDate: Date
let nextWateringDate: Date
}
struct PlantEntry: TimelineEntry {
let date: Date
let plants: [PlantRepresentation]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment