After working with complications for a few days, I feel confident saying the following about the update process for updates that happen at a prescribed interval:
- The system calls
requestedUpdateDidBegin()
- This is where you can determine if your data has changed. If it hasn't, your app doesn't have to do anything. If your data has changed, you need to call either:
reloadTimelineForComplication
if all your data needs to be reset.extendTimelineForComplication
if you only need to add new items to the end of the complication timeline.
- Note: the system may actually call
requestedUpdateBudgetExhausted()
instead ofrequestedUpdateDidBegin()
if you've spent too much of your complication's time budget for the day. This is the reason for this question.
- This is where you can determine if your data has changed. If it hasn't, your app doesn't have to do anything. If your data has changed, you need to call either:
- If you called
reloadTimelineForComplication
, the system will callgetCurrentTimelineEntryForComplication
(along with the future and past variants that get arrays, depending on your time travel settings) - This is conjecture as I haven't tested it yet, but I believe if you called
extendTimelineForComplication
that only thegetTimelineEntriesForComplication(... afterDate date: NSDate ...)
would be called. - The system will then call
getNextRequestedUpdateDateWithHandler
so you can specify how long until your complication requires a new update.
Apple's documentation is quite clear that you should not ask for updates too often, or conduct too much processing in the complication code or you will exhaust your time budget and your complication will stop updating. So, my question is: where and when do you do the update?
For context, my scenario is a URL with return data that changes up to two times per hour.
The most obvious place in which to put the URL fetch code is func requestedUpdateDidBegin()
Fetch the data, store it, and if there's no change, just return. If there was a change then extend or reload the timeline.
However, a URL fetch can be costly. Alternatives:
- Put the code on the phone app and send it over with a
WCSession
, but if the user closes that app then the updates will no longer happen. - Use push updates, but this isn't a web app, so I have no place to send them from.
- Obviously I will update all the data when the user interacts with the watch app, but that now means it only gets updated when the user uses the app, which negates the need for a complication.
Is there anywhere else? Can I have a periodic function in the watch app that isn't part of the complication? Where is the right place to fetch the data for a complication update?
requestedUpdateDidBegin()
counts against your time budget. Calls to both the reload and extend both clearly do. So that has me leaning towards doing it inrequestedUpdateDidBegin()
in the absence of other info, but I am still in search of an actual answer rather than my best guess.... – Westfahl