An NSURLSession
will allow you to add to it a large number of NSURLSessionTask
to download in the background.
If you want to check the progress of a single NSURLSessionTask
, it’s as easy as
double taskProgress = (double)task.countOfBytesReceived / (double)task.countOfBytesExpectedToReceive;
But what is the best way to check the average progress of all the NSURLSessionTasks
in a NSURLSession
?
I thought I’d try averaging the progress of all tasks:
[[self backgroundSession] getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *allDownloadTasks) {
double totalProgress = 0.0;
for (NSURLSessionDownloadTask *task in allDownloadTasks) {
double taskProgress = (double)task.countOfBytesReceived / (double)task.countOfBytesExpectedToReceive;
if (task.countOfBytesExpectedToReceive > 0) {
totalProgress = totalProgress + taskProgress;
}
NSLog(@"task %d: %.0f/%.0f - %.2f%%", task.taskIdentifier, (double)task.countOfBytesReceived, (double)task.countOfBytesExpectedToReceive, taskProgress*100);
}
double averageProgress = totalProgress / (double)allDownloadTasks.count;
NSLog(@"total progress: %.2f, average progress: %f", totalProgress, averageProgress);
NSLog(@" ");
}];
But the logic here is wrong: Suppose you have 50 tasks expecting to download 1MB and 3 tasks expecting to download 100MB. If the 50 small tasks complete before the 3 large tasks, averageProgress
will be much higher than the actual average progress.
So you have to calculate average progress according to the TOTAL countOfBytesReceived
divided by the TOTAL countOfBytesExpectedToReceive
. But the problem is that a NSURLSessionTask
figures out those values only once it starts, and it might not start until another task finishes.
So how do you check the average progress of all the NSURLSessionTasks
in a NSURLSession
?
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…