how to pass properties to swift 3 urlsession didFi

2019-09-15 07:35发布

问题:

I can successfully download a zip file in background with my app code with ios 10 and swift 3.

I use a backgroundsession data task:

let backgroundSessionConfiguration = URLSessionConfiguration.background(withIdentifier: (prefix + postfix))
        let backgroundSession = Foundation.URLSession(configuration: backgroundSessionConfiguration, delegate: self, delegateQueue: OperationQueue.main)

        var request = URLRequest(url: dlUrl )
        request.httpMethod = "GET"
        request.cachePolicy = NSMutableURLRequest.CachePolicy.reloadIgnoringCacheData

        let task = backgroundSession.downloadTask(with: request)

        task.resume()

But I wonder what is the best practice to pass some specific metadata to the delegate method after the download finished:

    func urlSession(_ session: URLSession,
    downloadTask: URLSessionDownloadTask,
    didFinishDownloadingTo location: URL){

I need inside this delegate some information about that download which depends e.g. on a choice a user made earlier. I am not able to get this data from the server or the url.

So I would like to have a variable or dictionary downloadType telling me what to do with the finished download, to have something like this in the delegate

if downloadType == "normal" ... do this
else ... do that

I am not sure if I can safely use properties of the class implementing the URLSessionDownloadDelegate protocol while the App was suspend? Will the class instance itself be restored when the download finishes while the app is suspended or will ios create a new instance of the class?

So will this always work:

class ServerCom: NSObject, URLSessionDownloadDelegate {
   var updateTypeStr = ""
  [...]
  func somePublic(setUpdateType: String) {
     self.updateTypeStr = setUpdateType

  [...]
    func urlSession(_ session: URLSession,
    downloadTask: URLSessionDownloadTask,
    didFinishDownloadingTo location: URL){
   [...] 

       if( self.updateTypeStr == "normal" ) { // do this
       else { // do that

Are there some better ways for that use case?

thanks in advance!

回答1:

Will the class instance itself be restored when the download finishes while the app is suspended or will ios create a new instance of the class?

You are responsible for saving and restoring this yourself.

Your app may be completely terminated (e.g. having been suspended, it can possibly be jettisoned due to memory pressure) in the intervening period while the daemon completes your background request, so you have to be able to save any relevant information to persistent storage and be able to load this from storage when the app restarts.

When testing apps with background sessions, I find it useful to have code that calls exit(0) to terminate the app. You never do that in a production app, but it's useful when testing your app's ability to recreate the necessary objects when the app is re-started when the background request finishes. The key point is that one should not attempt to use the "double tap home button and swipe up" to kill the app when doing this testing, because that will, by design, cancel the background requests, too. You want to test the scenario where your app has been terminated through the normal app lifecycle and has been restarted by the network daemon once the background request is done.