Ios: Does Force Quitting the App Disables Background Upload Using Nsurlsession

iOS: Does force quitting the app disables background upload using NSURLSession?

I can confirm now after a bunch of testing that background task will run ok if the app is just put into background. However, if user force quit the app manually, then iOS cancels all scheduled background tasks. So next time the app is launched I'm getting all the callbacks to the delegate with the error code of a canceled task.

Hope it helps someone looking into the same thing.

Does NSUrlSession continue file transfer if the app is killed from task manager?

If the system kills your app and your background session has active downloads, your downloads will continue and the system will launch your app when the downloads complete. However, if a user force quits your app, all tasks get cancelled.

Documentation for backgroundSessionConfigurationWithIdentifier:

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.
In addition, the system does not automatically
relaunch apps that were force quit by the user. The user must
explicitly relaunch the app before transfers can begin again.

NSURLSession with background configuration and app killed by user

Kudos to Rob because he showed me the right path.

So after the user kills the app, the system cancels all the pending tasks.


You can see that with the system.log:

Simulator/Debug/Open System Log...

How to catch what was already ongoing?

Instantiate again your Background NSURLSession. Do it elsewhere, but I'll do it in AppDelegate for this example.

The system knows (thanks to the identifier) that it is the same Background Session that before so it maps the pending tasks.

Then retrieve all the tasks. The canceled tasks are still there

The tasks will have a error that you can check.

Error Domain=NSURLErrorDomain Code=-999 "(null)" 
UserInfo={NSErrorFailingURLStringKey=http://your.api.com/url,
NSURLErrorBackgroundTaskCancelledReasonKey=0,
NSErrorFailingURLKey=http://your.api.com/url}

Also, with the tasks, you will get the Request URL, so you can map your app requests and do something.

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

// This is the code for Swift 2.x. In Swift 3.x this call is a bit different.
NetworkingManager.backgroundManager.session.getTasksWithCompletionHandler { (data, upload, download) in

for task in data {

NSLog("\(task.error)")
}

for task in upload {

NSLog("\(task.error)")
}

for task in download {

NSLog("\(task.error)")

let reason = task.error?.userInfo[NSURLErrorBackgroundTaskCancelledReasonKey] as? Int
let code = task.error?.code

if reason == NSURLErrorCancelledReasonUserForceQuitApplication &&
code == NSURLErrorCancelled {

NSLog("\(task.originalRequest)")
NSLog("\(task.currentRequest?.URL)")
}
}
}
}

NSURLErrorCancelledReasonUserForceQuitApplication -> The operation was canceled because the user forced the app to quit.

So we are on the right track.
If someone has a better solution, please share! I do not really like the mapping solution of my requests urls.

Resuming tasks using NSURLSession when app removed from background or on device reboot

Finally I come to conclusion that,

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.

For more details check Apple's documentation on NSURLSessionConfiguration Class Reference here.

NSUrlSession: is it possible to upload files in the background?

They DO work together.

What you need to do is the following:

Have a NSURLSessionConfiguration with background configuration

NSURLSessionConfiguration *conf = [NSURLSessionConfiguration backgroundSessionConfiguration:@"backgroundSession"];

Setup a NSURLSession (@property NSURLSession *urlSession)

Obtain the path to the file (fullPath)

Create the NSURLRequest (request)

Create a NSURLSessionTask

NSURLSessionTask*task = [self.urlSession uploadTaskWithRequest:request fromFile:fullPath];
[task resume];

And the task will run in background. You can get the status from NSURLSession delegate methods.

Cheers

NSURLSession background upload - need to enable background modes?

The official guide Background Execution declare three type of background executions:

  1. Executing Finite-Length Tasks - using UIApplication method

    beginBackgroundTaskWithName:expirationHandler: to execute finite
    time task.
  2. Downloading Content in the Background - using NSURLSession to
    download content. The NSURLSession provided by your app is run on
    separate system level daemon and when done, gets back to the app by
    the completion handler. (Your above mentioned implementation)
  3. Implementing Long-Running Tasks - Tasks that needs to be running for
    long time, are handled under this category, like audio, voip,
    location, download processes, update contents. These type of tasks
    needs the special UIBackgroundModes key mentioned in info.plist.

So answering your question, you don't need the UIBackgroundModes key, until you don't fall in the long-running tasks category.

How to resume NSURLSession download process after app force-quit and app relaunch?

After a force-quit the:

 NSURLSessionTaskDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error

delegate method will be called when the app is restarted. If the download task can be resumed the error object will contain the resume data:

[error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData].

Using this data you can resume the download process by creating a NSURLSessionDownloadTask with:

(NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData*)resumeData.

More info about that can be found in Life Cycle of a URL Session with Custom Delegates, step 13.



Related Topics



Leave a reply



Submit