2

I have created a class to download file using URLSession.

I noticed a weird behavior that when device in debug mode, it is downloading files. But if I remove device and run app manually, downloading is not working at all. Sometimes re-attaching device starts the download.

This is how I am creating URLSession :

private lazy var urlSession: URLSession = {
     let config                      = URLSessionConfiguration.background(withIdentifier: "org.company.id")
     config.isDiscretionary          = true
     config.sessionSendsLaunchEvents = true
     config.allowsCellularAccess     = true
   return URLSession(configuration: config, delegate: self, delegateQueue: nil)
}()

And here is my request download function :

func requestDownload(urlString: String){
    guard let url                = URL(string: urlString) else {return}
    downloadTask                 = urlSession.downloadTask(with: url)
    downloadTask.taskDescription = urlString
    downloadTask.resume()
}

Here is a link to that file downloader class : https://github.com/skdevil/PrakrstaFileDownloader

Any idea how to fix it ?

Sharad Chauhan
  • 4,821
  • 2
  • 25
  • 50
  • 1
    Debug! Log like crazy. Log into a file you can study after a run. Find out where things go wrong. – matt Apr 07 '18 at 13:22
  • @matt But the problem is when app is not in debug mode. In debug mode its working fine. I will do "unified logging" as suggested by Rob. – Sharad Chauhan Apr 09 '18 at 06:20

1 Answers1

4

The issue is that when you run it attached to your debugger, the app is never suspended, whereas on a device can be.

A couple of observations:

  • It is possible you have not implemented handleEventsForBackgroundURLSession in your app delegate or urlSessionDidFinishEvents(forBackgroundURLSession:) in your URLSessionDelegate. They're required for background downloads. We'd need to see those implementations to comment further.

    For more information see Downloading Files in the Background.

    FYI, I've issued a pull request on that repo, showing what you need to do to support background sessions.

  • Or, if you've done all of that correctly, note that you've set discretionary mode. This means that it will download when attached to power and wifi. Is that the case?

  • Note, I'd encourage doing some logging so you can see what's going on. But you cannot use Xcode's debugging mechanisms for this (because, as you've noticed, being attached to Xcode changes the behavior of the app).

    You can, instead, log using "unified logging" as outlined in WWDC 2016 video Unified Logging and Activity Tracing. That way, you can watch log messages from your iOS device on your macOS console, and you don't have to write your own file logging system. See point 3 at https://stackoverflow.com/a/25951564/1271826 for example of how to observe iOS log messages on macOS console. Or see that aforementioned WWDC video.

Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Thanks for updating my repo :) . Will do what you suggested and update this question accordingly. – Sharad Chauhan Apr 09 '18 at 06:21
  • discretionary mode - This means that it will download when attached to power and wifi. Can you please explain this ? – Sharad Chauhan Apr 09 '18 at 06:45
  • I updated my code as per your commit and added in appdelegate too. Still the downloading is working in debug mode only ( sometimes it works without it too but rarely) – Sharad Chauhan Apr 09 '18 at 06:51
  • 1
    Re `isDiscretionary`, see [the documentation](https://developer.apple.com/documentation/foundation/urlsessionconfiguration/1411552-isdiscretionary), which confirms that with this set to `true`, the OS has the right to defer the download until it sees fit (generally when on wifi and charging). The idea is that if you're downloading some huge resource, you might not want to unnecessarily consume the device's battery and the user's data plan. Try changing `isDiscretionary` and see if your behavior changes. – Rob Apr 09 '18 at 07:01
  • @sharadchauhan - Also note that background sessions (esp discretionary ones) can run slowly, so I don't know how long you're giving it to finish... – Rob Apr 09 '18 at 07:05
  • Somehow getting your commit, doing what you suggested and commenting "config.isDiscretionary" this line, it working continuously. Thank you so much! – Sharad Chauhan Apr 09 '18 at 07:23
  • 1
    Yes its taking little time to start but it is downloading. – Sharad Chauhan Apr 09 '18 at 07:31