9

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.

Wed
  • 553
  • 5
  • 20

1 Answers1

10

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).

Community
  • 1
  • 1
  • I already tried that demo but it seems that it isn't working. The started task never finishes. – Wed Jun 22 '16 at 20:53
  • What exactly about it isn't working for you? Please be specific. Again, you should edit your question, show the code you're trying, and describe the exact problem you're having. Questions without actual coding problems are more difficult to answer. –  Jun 22 '16 at 20:58
  • You answered my question already. My left problem is just that the demo from apple does not work. As I already wrote the problem is the task starts but never completes. – Wed Jun 23 '16 at 05:52
  • Are you following the instructions in the Readme that explain about using the crown to put the app in the background, wait until the handler fires and is finished, then open the dock? It does work if you watch the log and the dock occasionally should show a new time. What might be happening is that the system defers background tasks, as you're only permitted ~1/hour. –  Jun 23 '16 at 06:36
  • I'm following it, of course. I'm testing on the simulator, because xcode wont install symbols on my watch. I Try to wait for a longer period. – Wed Jun 23 '16 at 06:53
  • 2
    From my side, the background task starts, and the didFinish handler fires, so everything appears to be functional, albeit a bit inconsistent at times. Beta software is buggy. Can't really help with that aspect. You can file a bug report, continue to port your code to use the new functionality, and hope it is improved for beta 2! –  Jun 23 '16 at 07:06
  • I can also confirm what @PetahChristian is seeing. I have tried the sample code on both the simulator and on a device running watchOS3 Beta. It does not work in either case. One singular time I was able to get it to work correctly, but I have no idea why. I am also hoping that with a future release of watchOS3 this issues is fixed. – Nidal Fakhouri Jul 28 '16 at 15:33
  • In Xcode beta 4 the sample project is still broken. I see an almost continuous stream of WKApplicationRefreshBackgroundTasks come through, but never a WKURLSessionRefreshBacgkroundTask. Same thing happens with my own watch application. – jervine10 Aug 02 '16 at 13:22
  • Testet with Xcode beta 6 - and still the same :-/ . A lot of Background Tasks but the URL Session never prints "NSURLSession finished to url". Does anyone managed to get this working? – Dirk Aug 21 '16 at 20:26
  • 2
    Still unable to get this working in the GM and the demo project link is now 404. Pretty crazy. – RealCasually Sep 12 '16 at 07:44
  • Could you (original poster or the answer writer) please post some code? I checked the sample project but it doesn't have anything to do with complications. I couldn't find any code on Apple's docs or forums to show where and how to schedule a series of complications updates. For example: Who should schedule the background tasks? The first InterfaceController in the watch extension? Where (in what function or method) does scheduleBackgroundTasks go? How often should it be called? (since complication updates can theoretically go on forever) How to reconcile/cache for time travel results? – Erika Electra Feb 02 '17 at 05:02
  • Curious question I wanted to see if anyone could give an answer to. Where are you all calling your method to fire the original background task? I am calling in applicationDidFinishLaunching(), but it doesn't always seem to fire. – Zachary Bell Feb 28 '18 at 16:59