Could you explain what you mean by “accidentally dropped the completion handler in point # 1 above?
The standard sequence for being resumed in the background for NSURLSession background session events is:
The system resumes (or relaunches) your app
If it’s a relaunch, you re-create your background session
The system calls
-application:handleEventsForBackgroundURLSession:completionHandler:
to tell you what session to serviceYou save away the completion handler
The session starts sending you delegate callbacks
When it’s done it sends
-URLSessionDidFinishEventsForBackgroundURLSession:
You call the completion handler you saved in step 4
The gotcha I was specifically referring to relates to steps 4 and 7. If you fail to save the completion handler (step 4), or fail to call it (step 7), or do something else wrong (like accidentally clear it, or overwrite it), weird things are going to happen.
Another gotcha relates to the thread on which you call the completion handler. It must be called from the main thread. If you have your NSURLSession delegate set up to run on a secondary thread, you can’t call the completion handler directly from
-URLSessionDidFinishEventsForBackgroundURLSession:
, but instead must bounce to the main thread to do that job.
Also what would cause point # 2 of yours above to occur?
Imagine a scenario like this:
You start a download
The download completes and your
-URLSession:downloadTask:didFinishDownloadingToURL:
method is calledThat has to commit the download to your database
There’s some sort of other problem that causes that commit to deadlock
At this point you’re permanently blocked within the delegate callback, which is going to prevent NSURLSession sending your any other delegate callbacks.
A similar but harder-to-debug problem relates to delegate callbacks with completion routines. Consider this:
You start a download
The download encounters an authentication challenge
The system calls your authentication challenge delegate callback (
-URLSession:didReceiveChallenge:completionHandler:
or -URLSession:task:didReceiveChallenge:completionHandler:
)That callback fails to call the completion handler
Now this request is just stalled; it won’t even time out because all the timeout timers are suspended while waiting for the authentication challenge to be resolved.
I’ll respond to your big picture issue on your new thread.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"