Wed Wed - 5 months ago 435
Swift Question

Updating complication with Swift 3 and background task

For watchOS 3, Apple suggests updating the complication with

WKRefreshBackgroundTask
instead of using
getNextRequestedUpdateDate
.

How can I determine the time between two updates using the new approach?

I would only hack my data requesting (from an url) into
getCurrentTimelineEntry
and would update the complication, but I think that's not really what Apple would recommend.

A short code example would be a big help.

Answer

I generally covered this in a different answer, but I'll address your specific question here.

You're right that you shouldn't hack the complication controller to do any (asynchronous) fetching. The data source should only be responsible for returning existing data on hand as requested by the complication server. This was true for watchOS 2, and is still true in watchOS 3.

For watchOS 3, each background refresh can schedule the next one.

Overview of the process:

In your particular case, you can wait until your WKURLSessionRefreshBackgroundTask task finishes its downloading. At that point, schedule the next background refresh before completing your existing background task.

At that future time, your extension will be woken up again to start the entire background process again to:

  • Request new data from your web service
  • Handle the reply and update your data store
  • Tell the complication to update itself (which will use the new data on hand).
  • Update the dock snapshot
  • Schedule an upcoming background refresh task
  • Mark your current task as complete.

You can even chain a series of different background sub-tasks where each sub-task handles a separate aspect of a refresh cycle, and is responsible for scheduling the following sub-task.

Sample code:

If you haven't seen it, Apple provides its WatchBackgroundRefresh sample code to demonstrate part of this. You can use

WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate:userInfo:)

to schedule (either the initial, or) a future task before the present task completes.

Although their example uses a refresh button to schedule the next background refresh, the concept is the same, whether it is a user action or background task that schedules the next request).