What I want to achieve is the following:
- Complication(s) get updated in the background at intervals of 30 minutes
- Complication(s) get updated whenever the watch app runs and receives its own updated data
- Complication(s) get updated whenever the iOS app runs and the user changes a setting which affects the watch data (such as changing location of weather observations, or display units)
Items 1. and 2. seem to be straightforward, and nicely addressed here: What is the flow for updating complication data for Apple Watch?
However, for item 3, in the iOS app, I set up a WCSession instance and call transferCurrentComplicationUserInfo, sending the new settings as NSDictionary. In the watch extension, this invokes didReceiveUserInfo in WCSessionDelegate.
- (void)session:(WCSession *)session didReceiveUserInfo:(NSDictionary<NSString *,id> *)userInfo {
// Code here to apply the new settings
// ....
// Invoke a NSUSRLSession-based web query to get new data
[self queryForNewDataWithCompletionHandler:^(NCUpdateResult result) {
if (result == NCUpdateResultNewData) {
// Have new data from web to display
CLKComplicationServer *server = [CLKComplicationServer sharedInstance];
for (CLKComplication *complication in server.activeComplications) {
[server reloadTimelineForComplication:complication];
}
}
// Set date for next complication update to 30 mins from now
// ...
}];
}
The problem I am having is that watchOS is calling requestedUpdateDidBegin in a separate thread, shortly after it invoked didReceiveUserInfo and this starts executing BEFORE I have a chance to obtain updated data using the new settings in the newly received UserInfo dictionary from the app.
Consequently, the complications get updated twice in short succession - once by the WatchOS having called requestedUpdateDidBegin, which simply re-updates the complication with existing (stale) data, before I very soon after receive new data from the web and then have to update them again in my own code.
This seems unnecessary and a waste of resources, not to mention the limited budget of updates that Apple allows (supposedly 2 per hour).
Am I doing anything wrong here? How can I prevent watchOS2 from calling requestedUpdateDidBegin before I have had a chance to acquire new data from the web?