1

I'm working on an application that download files from our server (fairly large files). I manage the download files in foreground and background (without closing the application). My problem is with the case that the user intentionally closes the application using the multi-tasking screen.

In this case I'm getting a callback on didCompleteWithError the method and receive the error that has error.userInfo that contains the resume data NSData object under the NSURLSessionDownloadTaskResumeData key.

The question is: How this situation should be handled? Should I immediately start another task using the downloadTaskWithResumeData from the didCompleteWithError method, or I need to save the resumeData NSData object in the UserDefaults and use it the next time the application runs?

I tried to do something like this in the didCompleteWithError:

if (error?.userInfo[NSURLSessionDownloadTaskResumeData] != nil) {
                Logger.printLogToConsole(self.TAG, aMethodName: __FUNCTION__, aMessage: "Resume data was found");
                let req = task.originalRequest
                let languageCodeWrapped: AnyObject? = NSURLProtocol.propertyForKey("languageCode", inRequest:req!)!
                if let languageCode = languageCodeWrapped {
                    SessionDownloader.sharedInstance.downLoadWithResumeData(languageCode as! String, aResumeData: error?.userInfo[NSURLSessionDownloadTaskResumeData] as! NSData)
                    if taskDelegate != nil {
                        DownloadSessionDelegate.sharedInstance.setDelegateForTaskId(taskDelegate, taskId: "\(task.taskIdentifier)", code: languageCode as! String)
                    }
                }
            }

But something there is not working right, and I can't really debug it because I need to kill the app which basically kills the debugged process.

halfer
  • 19,824
  • 17
  • 99
  • 186
Emil Adz
  • 40,709
  • 36
  • 140
  • 187

2 Answers2

0

Its not working as app is already being terminated and only give you small time (around 5 seconds) to save your stuff.

And to handle your case please see following notes from apple docs

If an iOS app is terminated by the system and relaunched, the app can use the same identifier to create a new configuration object and session and retrieve the status of transfers that were in progress at the time of termination. This behavior applies only for normal termination of the app by the system. If the user terminates the app from the multitasking screen, the system cancels all of the session’s background transfers.

So looks like you have to define something custom in your case to handle this as you said NUUser defaults but I recommend to use NSURLCache.

Imran
  • 2,985
  • 19
  • 33
0

Saving it in NSUserDefaults would probably be the best bet. Then, when the user relaunches the app, recreate the background session using the same identifier, then recreate the tasks using the resume data. If any of them fail to resume, you'll get a new download. (Resuming is, after all, just best effort.)

Chances are good, however, that you won't be able to get resume data, because the tasks will be gone by the time you ask.

Also, if you are dealing with a lot of files, consider storing the resume data in a separate file so that NSUserDefaults doesn't get huge.

dgatwood
  • 10,129
  • 1
  • 28
  • 49