Many tasks (NSURLSessionDownloadTask) with a background session causes failure using AFNetworking

520 views Asked by At

We have recently migrated from AFHTTPRequestOperation to NSURLSessionDownloadTask using AFURLSessionManager in AFNetworking 3. Our users have the option of downloading items that can consists of up to around 5,000 files.

These files are mainly PDF and MP4 and range in size from 10 KB to 1 GB. As part of the migration to using NSURLSession and AFURLSessionManager we were excited to be able to hand these downloads off to the system when the app entered the background allowing the downloads to continue. But what we are experiencing is these downloads will begin to fail with an error message of

lost connection to background transfer service

-or-

"no such file or directory"

when the users selects to download upwards of 500 files, this can happen with the app in the background or foreground. We then receive these error messages on any future downloads until we kill and restart the app.

Any ideas if this is a limitation of iOS and NSURLSession with a background configuration or if we should be able to get this to work?

Our AFURLSessionManager looks like this:

NSURLSessionConfiguration *configuration =
[NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.our.app.identifier.downloads"];
[configuration setHTTPMaximumConnectionsPerHost:5];
AFURLSessionManager *sessionManager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
[sessionManager setCompletionQueue:dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0)];

And the tasks look like this:

NSURLSessionDownloadTask *downloadTask = [self.sessionManager downloadTaskWithRequest:[self requestForItem:item] progress:nil

 destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {

    NSString *filePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    return [NSURL fileURLWithPath:[filePath stringByAppendingPathComponent:@"fileid.ext"]];

} completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {

    // check for error and notify the ui of completion

}];
1

There are 1 answers

0
dgatwood On

IIRC, NSURLSession explodes in flames if you try to add more than a few dozen tasks to a session. By the time you get up to 500, you're pretty much guaranteed to break it. This is a known bug, as other folks on Stack Overflow have run into it and filed bugs about it. That said, please file a bug, because the more bugs Apple gets about the issue, the higher its priority will be.

The usual workaround is to keep an external queue of pending requests, and then add tasks to the session as other tasks complete.