Can't refresh WidgetView every minute

Viewed 849

I can't refresh my widgets every minute. Here is my getTimeline function;

let currentDate = Date()
let refreshDate = Calendar.current.date(byAdding: .minute, value: 1, to: currentDate)!
guard let widget = try? JSONDecoder().decode([myWidgets].self, from: widgetData)
let entry = widgetEntry(date: Date(), widget: widget[0])
let timeline = Timeline(entries: [entry], policy: .after(refreshDate))
completion(timeline)
WidgetCenter.shared.reloadAllTimelines()

I also tried refreshing every second with only refresing the date to show current time, but its stops refreshing after couple of seconds.

Then I tried this code below from @pawello2222 but widgets are not loading correctly with it;

    var entries = [widgetEntry]()
    let currentDate = Date()
    let midnight = Calendar.current.startOfDay(for: currentDate)
    let nextMidnight = Calendar.current.date(byAdding: .day, value: 1, to: midnight)!

    for offset in 0 ..< 60 * 24 {
        guard let widget = try? JSONDecoder().decode([myWidgets].self, from: widgetData)
        let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: midnight)!
        entries.append(widgetEntry(date: entryDate, widget: widget[0]))
    }

    let timeline = Timeline(entries: entries, policy: .after(nextMidnight))
    completion(timeline)
1 Answers

I also tried refreshing every second with only refresing the date to show current time, but its stops refreshing after couple of seconds.

You only have a limited number of refreshes available to your Widget. If you call WidgetCenter.shared.reloadAllTimelines() every second, your Widget is likely to run out of available updates very quickly.


Also, you shouldn't call reloadAllTimelines() in getTimeline():

...
completion(timeline)
WidgetCenter.shared.reloadAllTimelines() // remove this

Then I tried this code below from @pawello2222 but widgets are not loading correctly with it

I assume you're referring to this answer: Updating time text label each minute in WidgetKit

Note that in your code guard let may not pass through:

for offset in 0 ..< 60 * 24 {
    guard let widget = try? JSONDecoder().decode([myWidgets].self, from: widgetData) // you need `else { ... return }` here
    let entryDate = Calendar.current.date(byAdding: .minute, value: offset, to: midnight)!
    entries.append(widgetEntry(date: entryDate, widget: widget[0]))
}

See: When to use guard let rather than if let

Related