urlSession(_:task:didCompleteWithError:) does not fire when session configured for background

Hardware: iPhone 12/iOS 15.1.1

I am having problems getting urlSession(_:task:didCompleteWithError:) to fire when session configured for background.

I set up my background session and uploadTask as such:

let config = URLSessionConfiguration.background(withIdentifier: "my.unique.session.identifier")
config.isDiscretionary = false
config.sessionSendsLaunchEvents = true 
config.allowsCellularAccess = true
config.httpMaximumConnectionsPerHost = 1
config.timeoutIntervalForRequest = 30
config.timeoutIntervalForResource = 60
let session = URLSession(configuration: config, delegate: yourDelegate, delegateQueue: nil)

let task = session.uploadTask(with: request, from: data)
task.resume()

First, I confirmed that I can upload using the above code.

Then to simulate a timeout, I set a breakpoint in Charles Proxy on the response. When triggered, I just wait. urlSession(_:task:didCompleteWithError:) is never called, no matter how long I wait. I can "see" the background session periodically retrying the upload, because I having logging in urlSession(_:task:didSendBodyData:). Every time didSendBodyData is called, it triggers the breapoint in Charles Proxy. And I wait. didCompleteWithError never gets called.

One more observation: if I change the session config from 'background' to 'default', didCompleteWithError is triggered.

Thanks!

Replies

I may have an answer... I originally had timeoutIntervalForResource set to the default of 7 days. When I uninstalled, then reinstalled, and ran the app with the new timeout values, I started getting timeouts. This leads me to believe that the background session settings were still in effect using the 7 day default. Could someone comment on the possibility of this? Also, is there a way to kill the background session of the app without uninstalling/reinstalling it?