1
votes

I have an application which would support downloading the content to local disk. Users can choose the items they want to save. After downloading complete, I will unzip the downloaded file and encrypt then save to local. I use NSURLSession with backgroundConfiguration to support background download. I want user to access the downloaded content ASAP, so I implement my own queue to handle the download items. I wish the download mechanism could work both on foreground and background. Here are some mechanisms and their result

  • Method 1:

Create each download task first, and enqueue the object

downloadObj.downloadTask = [session downloadTaskWithRequest:request];

downloadObj.taskIdentifier = downloadObj.downloadTask.taskIdentifier;

[Queue enqueue:downloadObj];

Process the head object in the queue

obj = [Queue objectAtIndex:0];
[obj.downloadTask resume];

Handle next object in URLSession delegate function

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {

   finishObj = [Queue findObjFromIdentifier:downloadTask.taskIdentifier];

   nextObj = [Queue findNextObj:finishObj];

   [nextObj.downloadTask resume];

   [Queue removeObject:finishObj];

}

This method could work properly when app always in foreground. When the app enter background, all the created downloadTasks seems to resume automatically. So they will share the bandwidth at the same time. It doesn't follow FIFO....

  • Method 2:

Create the download task in URLSession delegate function, and resume directly

This method only download the running download task when app has already entered background.

Anyone can give me some advise about the background with First In First Out property?

2
We have the same problem. Did you find any solution?Jonathan Crooke

2 Answers

0
votes

I think what you need is to set the httpMaximumConnectionsPerHost on URLSessionConfiguration object to 1. That means session will make one request at the time so it would be FIFO as you call it. There wouldn't even be a need to store and resume the next task in the delegate callback method, it would all happen automatically.

0
votes

You can't keep NSURLSessionTask objects around like that without starting them. The assumption is that you create the object, tweak its settings, and start it immediately. As a result, certain timeouts start counting down as soon as you create the object, IIRC. So if you create the object and then start it a minute or two later, it will time out before it even starts. I'm pretty sure that this fact is not mentioned in any of the documentation, unfortunately.

A much better (read "likely to work") approach is to store the NSURLRequest object, and enqueue that. Then, at the appropriate time, dequeue the request, create a task, and start executing it.

Also, URL sessions aren't anywhere close to FIFO unless you limit the number of concurrent connections to 1. Otherwise, you'll hit the maximum number of concurrent requests per host, and it won't start any more requests for that host until one finishes, but requests for other hosts will start immediately.