Search code examples
swiftswiftuiios14widgetkit

iOS 14 Widget auto-refresh every day


I have played around with the new iOS 14 widgets, and seems to be working almost fine, except the auto-refresh. My goal is to have my widget refreshed every midnight (so, only once per day, and of course occasionally if something happens in my app). In XCode I played around with it setting to refresh every minute and seemed to work quite randomly - so it maybe refreshed once in my tested 10 minutes, but thought, it's OK as I read refreshes are handled by iOS so it might come sooner or later, but will eventually come.

Now, I have published this version of my app and today morning (around 8am, so well after midnight) I checked my widget and didn't update today.

My question, am I doing something wrong? Or is it simply not that stable yet?

My timeline contains only one item with date: now and refresh policy set to .after(nextMidnight). I also tried it with refresh policy .atEnd, but as I have only one item in the timeline which is set to now, wouldn't it try to refresh continuosly? I thought, .after is the better approach.

If it's relevant, it is StaticConfiguration and not IntentConfiguration (to be honest, I still have to dig into what the difference here is...).

The code snippet:

    func getTimeline(in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
        let now = Date()
        let calendar = Calendar.current
        var dateComponents = DateComponents()
        dateComponents.year = calendar.component(.year, from: now)
        dateComponents.month = calendar.component(.month, from: now)
        dateComponents.day = calendar.component(.day, from: now) + 1
        dateComponents.hour = 0
        dateComponents.minute = 0
        dateComponents.second = 0
        let nextUpdate = calendar.date(from: dateComponents)
        
        completion(Timeline(entries: [SimpleEntry(date: now)], policy: .after(nextUpdate!)))
    }

Solution

  • Actually, it seems to be I overlooked it, the widget actually refreshes, it was me, who didn't refresh the data itself. (I'm using UserDefaults to share data between my app and the widget, and even though the widget refreshed properly, as the data in UserDefaults was not updated, the same was shown over and over again.)