Setting the TimelineProvider refresh interval for Widget
Right now my Widget makes about 1 request per second. I want to change it to 1 request in 1 hour.
I get some errors on the line with let timeline = ...
like Value of optional type 'Date?' must be unwrapped to a value of type 'Date'
and some more.
Any suggestions what could be wrong:
struct Provider: IntentTimelineProvider {
let networkManager = NetworkManager()
func placeholder(in context: Context) -> SimpleEntry {
SimpleEntry(date: Date(), configuration: ConfigurationIntent(), clubname: networkManager.clubName)
}
func getSnapshot(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) {
let entry = SimpleEntry(date: Date(), configuration: configuration, clubname: networkManager.clubName)
completion(entry)
}
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
var entries: [SimpleEntry] = []
// Generate a timeline consisting of five entries an hour apart, starting from the current date.
let currentDate = Date()
for hourOffset in 0 ..< 5 {
let entryDate = Calendar.current.date(byAdding: .hour, value: hourOffset, to: currentDate)!
let entry = SimpleEntry(date: entryDate, configuration: configuration, clubname: networkManager.clubName)
entries.append(entry)
}
//wie oft geupdatet werden soll
let nextUpdate = Calendar.current.date(byAdding: .hour, value: 1, to: Date())
let timeline = Timeline(entries: entries, policy: .after(nextUpdate))
completion(timeline)
}
}
You shouldn't rely on the TimelineReloadPolicy
- it specifies the earliest date when the Timeline is refreshed, it is not guaranteed that it reloads at that specific time.
From my observations, a Widget is more likely to reload the timeline with the atEnd
policy.
A policy that specifies that WidgetKit requests a new timeline after the last date in a timeline passes.
Here is a possible solution:
func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> Void) {
print("getTimeline")
let entries = [
SimpleEntry(date: Date()),
SimpleEntry(date: Calendar.current.date(byAdding: .minute, value: 1, to: Date())!),
]
let timeline = Timeline( entries: entries, policy: .atEnd)
completion(timeline)
}
Note that the last entry may or may not be used. If the timeline is refreshed immediately after the second entry's date, the second entry won't be shown. However, sometimes the timeline may be reloaded with a delay - then the second entry will be visible (until the timeline is refreshed).