WKURLSessionRefreshBackgroundTask is not called when trying to do a background update in watchOS

I am working on a complication to get scheduled data from a web service. Every 20-30 minutes (or manually) I plan a WKRefreshBackgroundTask for this.

Apparently from Apple, I want the OS to process a selection of this data using the NSURLSession background.

This is the function I use to load the data I need:

 func scheduleURLSession() { print("\nScheduling URL Session...") let backgroundSessionConfig:URLSessionConfiguration = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString) backgroundSessionConfig.sessionSendsLaunchEvents = true let backgroundSession = URLSession(configuration: backgroundSessionConfig) let downloadTask = backgroundSession.downloadTask(with: URL(string: "https://www.myserver.com/somedata")!) downloadTask.resume() } 

A few things about this:

  • It is called when I plan it. I see his expression print in the console.
  • This is almost identical to Apple's example.
  • I missed the url. The same URL works just fine on iOS / watchOS apps, so nothing happens to it.

The problem is that I call resume() on the task and let it wake my application when it is finished, but that doesn't seem to be either.

When it is complete, it should return to the WKExtensionDelegate handler:

 func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) 

like WKURLSessionRefreshBackgroundTask , but it is not.

My code, identical to the Apple sample code, then creates another session, but joins it using the WKURLSessionRefreshBackgroundTask identifier. A delegate is set here to handle the loaded data. Check the code:

 func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) { for task in backgroundTasks { switch task { case let backgroundTask as WKApplicationRefreshBackgroundTask: print("\nWatchKit - WKApplicationRefreshBackgroundTask") // self.updateComplicationDataArrivalTimes(backgroundTask) self.scheduleURLSession() backgroundTask.setTaskCompleted() case let snapshotTask as WKSnapshotRefreshBackgroundTask: // Snapshot tasks have a unique completion call, make sure to set your expiration date print("\nWatchKit - WKSnapshotRefreshBackgroundTask") snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil) case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask: print("\nWatchKit - WKWatchConnectivityRefreshBackgroundTask") connectivityTask.setTaskCompleted() case let urlSessionTask as WKURLSessionRefreshBackgroundTask: print("\nWatchKit - WKURLSessionRefreshBackgroundTask") let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier) let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) print("Rejoining session ", backgroundSession) urlSessionTask.setTaskCompleted() default: // make sure to complete unhandled task types task.setTaskCompleted() } } } 

But then again, it seems he never returns. I can’t understand why this works, even though the code is identical to the Apple sample code for this project: WatchBackgroundRefresh: using WKRefreshBackgroundTask to update WatchKit applications in the background .

Are there any settings in my project that I am missing? I put all this code in ExtensionDelegate , new in watchOS 3. I also agree with WKExtensionDelegate and URLSessionDownloadDelegate .

Thanks for your help in advance!

+6
source share
2 answers

I did it all! I began to look a lot at WWDC'16 videos / notes, comparing them with an example of this stream with the same problem that we encountered. There, the guy, “Daniel Fontes” publishes his “recipe” to make it work (pay attention, not the accepted answer!), And this in combination with the video worked for me.

What I did to make an example of Apple:

  • Make MainInterfaceController URLSessionDelegate
  • Create a local variable: var savedTask:WKRefreshBackgroundTask?
  • In the handle( backgroundTasks:) function, save WKURLSessionRefreshBackgroundTask in the local variable self.savedTask = task - not task.setTaskCompleted () (!!)
  • In urlSession - didFinishDownloading: set the saved task: self.savedTask?.setTaskCompleted() after you read the received data.
  • Make sure that the resource you are accessing is https: //, otherwise add "Application Transport Security Settings" to your Info.plist file.

Hope this helps!

ps. this works in simnulator (xcode 8.3.3, watchOS 3.2)

+4
source

I never got an Apple example, but I worked with updating the background. Unlike their example, you will need to make yourself a session delegate. So instead, create a background session as follows:

let backgroundSession = URLSession (configuration: backgroundSessionConfig, delegate: self, delegateQueue: nil)

I have a detailed code example here (see question code):

WatchOS 3 WKApplicationRefreshBackgroundTask didReceiveChallenge

Hope this helps.

+3
source

Source: https://habr.com/ru/post/1013169/


All Articles