Cancelling URLSessionUploadTask not triggering delegate callback

Hi developers,

I'm facing a weird issue with URLSessionUploadTask.

I created a URLSession using background config:

let config = URLSessionConfiguration.background(withIdentifier: identifier)
config.httpMaximumConnectionsPerHost = 1
config.allowsCellularAccess = true
config.sessionSendsLaunchEvents = true
config.waitsForConnectivity = true

let backgroundURLSession = URLSession(configuration: config, delegate: self, delegateQueue: OperationQueue.main)

Started a task using this code:

let task = backgroundURLSession?.uploadTask(with: urlRequest, fromFile: fileURL)
task?.taskDescription = "someIdentifier"
task?.resume()

Now when I'm trying to cancel this task (whenever the user presses the cancel button on UI), the cancel() method is not calling the delegate method as mentioned in the documentation. urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)

Code used to cancel the task:

backgroundURLSession?.getAllTasks { tasks in
    for task in tasks where task.taskDescription == identifier {
      task.cancel()
      break
    }
}

While debugging I can see that task.cancel() is getting called and the state of the task is getting changed from 0 i.e. running to 2 i.e.canceling.

Any help would be appreciated. Thanks in advance!

Now when I'm trying to cancel this task (whenever the user presses the cancel button on UI), the cancel() method is not calling the delegate method as mentioned in the documentation.

Since it does sound like you are implementing this in the foreground then are you implementing the delegate methods for URLSessionDelegate or URLSessionDataDelegate?

Notice the note on the URLSessionDataDelegate documentation:

Completion handler blocks are primarily intended as an alternative to using a custom delegate. If you create a task using a method that takes a completion handler block, the delegate methods for response and data delivery are not called.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com

The important thing to note is when an upload completes successfully (i.e. user did not press cancel), the delegate methods are called properly with a successful response.

Okay, and you can verify that your tasks filtering method is finding the task your want to cancel, correct? I suspect that you are, but I just wanted to double check. Anyways, being how this behavior conflicts with the documentation for cancel:

Once a task is marked as being canceled, urlSession(_:task:didCompleteWithError:) will be sent to the task delegate, passing an error in the domain NSURLErrorDomain with the code NSURLErrorCancelled.

If you are not able to make progress here, open a TSI and I can look at a sample that reproduces this issue in greater detail.

Matt Eaton
DTS Engineering, CoreOS
meaton3@apple.com
Cancelling URLSessionUploadTask not triggering delegate callback
 
 
Q