I have a server that keeps 2 booleans. These booleans change every 15 seconds.
Whenever I wake my Apple Watch, I want the complication to show the current state. How can I do it withough exhausting the budget early on?
The best way would be to fetch the newest state into the complication whenever I wake my watch. The only possible way I see would be to poll the server (either directly or via my phone) every 15 seconds. The problem is that I'd soon use up all the allotted time.
It would be great if I could make the complication only update when the watch was woken up. Can that be done?
Is there a way to not fetch data unless you need it?
No.
By "waking the watch," you're speaking of activating the watch either by interacting with it, or by raising your wrist. Regardless of the manner, the watch can either wake to the watch face, or to the last activity (which is controlled by the Wake Screen setting).
If it wakes to the watch face, this is independent of your app, watch extension, or complication controller. There is no notification you can use to handle that scenario.
If it wakes to an activity, it may not be your activity. If it were your activity, all you could do would be to stop updating when your watch app was active.
Either way, there is no contingency to only update the complication when the watch is awake.
If you think about what you're asking, it runs contrary to Apple's guidelines, as users expect to glance at the watch face and already see current complication data. The system expects you to provide updates when the watch is not awake, so the information will be immediately visible when the watch does wake.
Updating Complication Data
Of the available update approaches, these won't handle your requirements:
PKPushTypeComplication push notifications
This would be ideal, if you were not updating frequently and constantly throughout the day.
Apple applies a daily limit to the number of pushes of this type that you send from your server. If you exceed the limit, subsequent pushes are not delivered.
Scheduled automatic updates
The issue here is that the minimum scheduled update interval is 10 minutes, so you wouldn't have current complication info for the remaining 9-3/4 minutes.
Scheduled updates are useful for apps whose data changes at predictable times. When a scheduled update occurs, ClockKit calls the requestedUpdateDidBegin or requestedUpdateBudgetExhausted method of your data source first.
These approaches might handle your requirements, but you'd have to try them and determine which one meets your needs.
Watch extension + background NSURLSession
This may place more of a drain on battery, but it would work even if not in range of the phone.
Manual update via WCSession
transferCurrentComplicationUserInfo
If you're in range of your phone, the more likely approach would be for your phone to (always) poll your server, then provide constant updates.
When your iOS app receives updated data intended for your complication, it can use the Watch Connectivity framework to update your complication right away. The transferCurrentComplicationUserInfo: method of WCSession sends a high priority message to your WatchKit extension, waking it up as needed to deliver the data. Upon receiving the data, extend or reload your timeline as needed to force ClockKit to request the new data from your data source.
Note that complication transfers are budgeted in iOS 10. This approach would not work if you were performing large numbers of updates per day.
Having said all that, an alternate approach would be to monitor these booleans on the server side, and only send out a notification if there was a problem or change. You didn't explain exactly what these booleans indicate, but there are other approaches for monitoring, which would avoid you having to constantly poll a server (from your phone or watch).
If that's not an option, you really should consider either viewing the server data on your phone, or switching to a far less frequent update interval for your complication. Apple discourages such frequent updates, and even their own (stock or weather) complications are not updating several times a minute.
Update:
What if I only wanted to update the complication when user requested it himself(=clicked the complication)? He is not really interested in the state all the time.
The user needs to consider what a complication is meant to be. It's designed to be regularly updated to show current information. There's no mechanism to not update the complication because the user is mostly not interested in knowing the state.
Could you tap on a complication to open its app? Yes. But the complication itself would be showing stale data, and the user would have to do more than raise their wrist to see current state.
If you consider what the user is asking, they're not describing a complication (which shows current state), but a way to see the current state when they request it.
That mechanism is different from a complication. They're really describing a Glance (or an app) which the user swipes up (or opens) to see.
If they want live updates, it can be done via WCSession
updateApplicationContext
.
Use the updateApplicationContext:error: method to communicate recent state information to the counterpart. When the counterpart wakes, it can use this information to update its own state. Sending a new dictionary with this method overwrites the previous dictionary.
The way that works is your phone sends background updates to the watch. The watch stores the most recent update, which will be available to it when your app or Glance wakes up. The user views the app or Glance, and it displays the most recent value which the watch stored. While open, it continues to update itself as new updates arrive. While closed (e.g., inactive, asleep), the watch stores the most recent update on behalf of your app or glance.
If the user doesn't need the app or glance to update itself every 15 seconds, then you wouldn't need to poll, and you could simply use a NSURLSession
to fetch the current state when the extension awakes.
If you explain to the user that there's no way to update a complication when the user raises their wrist, and that they don't care about knowing the state all the time (which a complication is meant to do), then show them what a Glance can do, you'll find it far easier to accomplish what the user seems to want, ideally without unnecessarily draining the battery.