We are migrating ClockKit
complications to WidgetKit
in our watch app (watchOS 9+). The migration went smoothly, UI part works just fine. However, we've hit the wall with widgets not updating when requested by the watch app. I believe we are missing something very simple and fundamental, but couldn't find what exactly so far. Advice and tips would be very welcome! 🙇♂️
Our implementation details:
- Whenever data is changed in the main app, the updated data is submitted to the watch app via
WatchConnectivity
framework usingWCSession.default.transferCurrentComplicationUserInfo(_:)
. According to documentation, this method should be used to transfer complication-related data, since it will wake the watch app even if it is in the background or not opened at all. - Watch app receives updated data and stores it in
UserDefaults
shared with Watch Widget Extension hosting WidgetKit complications via App Group. - Watch app then request widget timeline reload via
WidgetCenter.shared.reloadAllTimelines()
. According to documentation, it reloads the timelines for all configured widgets belonging to the containing app, so it seems the appropriate way to reload WidgetKit complications. - Widget Timeline Provider class in Watch Widget Extension reads updated data from shared
UserDefaults
and uses it to provide the updated snapshot for widget views to render.
We believe our implementation logic is correct, but it doesn't work, for some reason. Widgets sometimes update when the watch app is opened, but not always. The most definitive way to force widgets to update is to switch to a different watch face, which confirms that the Widget Timeline Provider has access to properly updated data.
P.S. We are aware of the daily reload budget imposed on widgets, so we use widgets reload trigger sparingly. Anyway, according to documentation, reload budget is not effective when in DEBUG mode, but widgets won't reload even in DEBUG mode.
Thank you!
The system will decide on its own when or if it will accept your reload request (and at a given time). You can use Console.app to monitor processes related to reloading to see if there is a reason at the system level why your Widget isn't reloading. I would start with the Widget process on your Watch (the name of the target) to see why the updates aren't happening. The system logs can be very helpful and even provide information as to whether you've exceeded your daily budget.
Rico
WWDR - Software Engineer