2

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)
Baturay Koç
  • 169
  • 3
  • 14
  • Does this answer your question https://stackoverflow.com/a/64086553/12299030? – Asperi Nov 05 '20 at 07:04
  • @Asperi I tried that solution, everything working great without images. But when I put a background Image or even a system image on a HStack, its not rendering, only the placeholder. – Baturay Koç Nov 05 '20 at 12:23
  • I don't see any image in your code snapshot. Would you provide reproducible example based on what you commented above? – Asperi Nov 05 '20 at 13:00

1 Answers1

0

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

pawello2222
  • 46,897
  • 22
  • 145
  • 209
  • I think the problem is in my view. After trying your suggestion it worked in a simple view with only image and time. Do you know anyway to update the widget data whenever the JSONDecoder data changes? – Baturay Koç Nov 05 '20 at 16:13
  • @BaturayKoç It depends on how/when the data changes. In your question there is no information as to what the `myWidgets` variable is. I suggest you create a new question describing your issue. I'll try to help you there. – pawello2222 Nov 05 '20 at 16:26