I have an public transport app with realtime departure data for trains.
I would like to add a complication that shows the departure time of the next train.
Is it possible to show (or refresh) realtime data on a complication? For example, showing "3 min. to station X." The data could change every minute, based on info that comes from the public transport API.
How should I accomplish this on watchOS 2 or watchOS 3?
I know the ETA app shows travel times in a complication, but I'm not sure how they achieve that.
Are realtime updates possible?
Complications aren't designed to show realtime data. Frequent updates can affect energy efficiency and impact the battery (on both watch and phone).
To minimize power usage, ClockKit asks you to provide as much data as you have available and then caches the data and renders it when needed.
While there is no fixed number of times a complication timeline can be reloaded, the complication data source is subject to a daily execution time budget.
If your app’s data changes frequently, it might be difficult to provide enough data to display in a complication. Worse, if you refresh your complication data too frequently, you may exceed your execution time budget and your complication might not be updated until the following day.
Once the daily budget is exhausted, calls to reloadTimeline
(and extendTimeline
) do nothing.
If your complication has already exceeded its allotted daily budget for execution time, calls to this method do nothing. Call this method sparingly.
How can a complication display relative times?
How could a complication be frequently updated?
You could use a complication push update (either from a remote server, or locally from the phone in iOS 10).
There is a limit of 50 complication push updates per day.
You could fetch data on the phone and use transferCurrentComplicationUserInfo
.
In watchOS 2, this was only subject to the daily budget. In watchOS 3, this is now limited to 50 transfers per day.
See Is transferCurrentComplicationUserInfo more suitable for complication update? for more details.
In watchOS 2, you could use getNextRequestedUpdateDate
to schedule the next time to update your complication.
This can't occur more often than every ten minutes.
Note that watchOS 3 apps should be upgraded to use background refresh app tasks. The main benefit is that background tasks would be able to do more than merely update your complication. They can also handle fetching data, updating your model once the data arrives, as well as updating your dock snapshot.
Finally, you can schedule a manual update. In watchOS 3, the recommended way to do this would via a background refresh app task.
The task budget permits 4 tasks per hour. See scheduleBackgroundRefresh
for more details.
Note that background refresh app tasks must not use more than 10% CPU.
Recommended WWDC 2016 sessions
208 What's New in watchOS 3 introduces some of these topics.
804 Designing Great Apple Watch Experiences discusses when and why to update your watch apps.
218 Keeping Your Watch App Up to Date provides details about using background tasks to update your complication, app, and dock snapshot.
As mentioned in the talks, you should schedule your updates around the times when they would be needed.
For your use case, examples would be only when public transit is running, and only when the regularly scheduled departure times would be affected by a delay.
Apple sample code
Apple provides WatchBackgroundRefresh sample code demonstrating how to use WKRefreshBackgroundTask
to update WatchKit apps in the background.
To update any active complication within a background task, you would simply add code to reload (or extend) the timeline:
let complicationServer = CLKComplicationServer.sharedInstance()
for complication in activeComplications {
complicationServer.reloadTimelineForComplication(complication)
}