Reputation: 2221
I am experiencing a strange issue from time to with my NSURLSessionDownloadTasks (using a background download configuration).
It is always related to errors with NSURLDomain code NSURLErrorBackgroundSessionWasDisconnected (-997). The error itself usually seems to be coming from the app generically crashing or being forcefully closed during development from Xcode.
The relevant code boils down to
- (void)download:(NSURLRequest *)request
{
NSURLSessionDownloadTask *downloadTask = [self.urlSession downloadTaskWithRequest:request];
[downloadTask resume];
}
- (void) URLSession:(NSURLSession *)session
downloadTask:(NSURLSessionDownloadTask *)downloadTask
didFinishDownloadingToURL:(NSURL *)tempLocation
{
NSLog(@"task %@ didFinishDownloadingToURL with status code %@", downloadTask, @([downloadTask.response statusCode]));
}
- (void) URLSession:(NSURLSession *)session
task:(NSURLSessionTask *)task
didCompleteWithError:(NSError *)error
{
NSLog(@"task %@ didCompleteWithError %@", task, error);
}
The problem in these cases is, that the same NSURLSessionDownloadTask gets two (instead of only one expected) call in -[NSURLSessionTaskDelegate URLSession:task:didCompleteWithError:]
. Once without an error (which aligns to a call with a 200 OK response code to -[NSURLSessionDownloadDelegate URLSession:downloadTask:didFinishDownloadingToURL:]
) and then another time, usually a couple seconds later with an error (-997). Both times it's exactly the same memory address for the task being passed into these delegate methods.
Has anybody else experienced something similar? I am not expecting that second callback after I was already told that my task succeeded. Is there any obvious reason why the NSURLSession may still hold on to a task it reportedly finished already but then all of a sudden thinks it should inform me that it's lost connectivity to it background transfer service?
Upvotes: 0
Views: 1414
Reputation: 924
FWIW, I had a similar issue because I was updating the UI from the NSURLSession delegate methods, which run in background thread.
So, the solution for me was to move the UI-related code to run on the main thread as below:
dispatch_async(dispatch_get_main_queue(), ^{
//code updating the UI.
});
Upvotes: 1