NSURLSessionDownloadTask stops in the background, slowly recovering in the foreground

I am creating a background session using this code ...

let configuration = URLSessionConfiguration.background(withIdentifier: UUID().uuidString) configuration.sessionSendsLaunchEvents = true configuration.isDiscretionary = false self.session = Foundation.URLSession(configuration: configuration, delegate: self, delegateQueue: nil) 

... and load tasks using this code:

  let downloadTask = self.session.downloadTask(with: request as URLRequest) downloadTask.resume() 

My request objects are as follows:

  let request = NSMutableURLRequest(url: someURL) request.httpMethod = "POST" request.addValue("application/json", forHTTPHeaderField: "Content-Type") do { try request.httpBody = JSONSerialization.data(withJSONObject: someDictionary, options: JSONSerialization.WritingOptions()) } catch let error as NSError { // logging calls } 

Downloadable resources comprise ~ 20 MB zip files.

I can run four parallel downloads in the foreground without any problems. All expected delegate methods are called, and the transfer completes at normal speed.

The problem that I see is that if I start the download in the foreground, and then click the home button, the downloads will sometimes come in. I tried to keep the device active, and the network was spinning for an hour, and the transfers still did not end in the background. Also, when I bring the application back to the forefront, the transfer does not start right away. If I let the program sit in the foreground for ~ 4 minutes, they wake up and start working again. They resume in the percentage during which they were when the application quits in the background and will be transmitted at normal speed until completion. There are no errors, and the transfer is ultimately successful. It simply β€œleaves” in the background and resumes very slowly when the application returns to the forefront.

I am testing an iPhone on an iPhone iOS 10. I am not connected to Xcode or an external power source and I am starting the application coldly. I can reproduce the problem both on WiFi and on cellular. I uninstalled the application and reloaded it several times.

I am having trouble tracking this, because it works fine for about 20% of the time. I did not find any specific set of variables that make it work sequentially or fail. This happens more often when multiple downloads occur, and in this situation all downloads show the behavior described above.

Any guidance would be greatly appreciated!

Matt

+5
source share
1 answer

The behavior you describe sounds like an error in iOS, but a few things I would like to try:

  • Try setting the discretionary value to YES. This limits the speed of background restarts.
  • Make sure that you do not accidentally create a new background session with the same identifier as the existing one (unless you have just been rewritten to handle events and only after calling the completion handler) during one run.
  • Make sure that you are not subclassing any of the classes, in particular NSURL or NSURLRequest.
  • Try the shouldUseExtendedBackgroundIdleMode parameter in YES.
  • Try adding an enabling background selection to UIBackgroundModes.

None of the last two should help, and if they do, indicate a mistake.

In addition, IIRC, your application may receive a penalty if it is restarted too many times in the background, so if you make a bunch of short queries in the background job, you probably shouldn't. And if your application crashes when it resumes in the background, it can also be very bad.

Finally, make sure that you simply go to the main screen. If you forcefully close the application (double-tap, swipe the screen), background requests will stop. And this is the expected behavior.

If none of these tips help, write a bug report on bugreporter.apple.com because what you are describing is not expected behavior.

0
source

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


All Articles