I am sure this has already occured to someone but I could not find a trusted source (on Stackoverflow or elsewhere) to solve this.
I have to download a (finite) number of files. I don't know their size prior to downloading them. Their size can greatly change and I don't know it before beginning the download.
It can often happen that I have 9 really small files and 1 really big file.
If I use NSProgress
with its "children" feature, I will very quickly show a completion of 90%, then the UI will appear to be stuck (even though it is not the case) since the last file is much bigger.
Here is an example code where I simulate a large file.
- (void)viewDidLoad
{
[super viewDidLoad];
nbTasks = 10;
mainProgress = [NSProgress progressWithTotalUnitCount:nbTasks];
[self launch];
}
- (void)launch {
for (int i = 0; i < nbTasks; ++i) {
[mainProgress becomeCurrentWithPendingUnitCount:1];
[self launchWithNumber:i];
[mainProgress resignCurrent];
}
}
- (void)launchWithNumber:(int)count {
int max = count == 0 ? 100 : 10;
NSProgress *localProgress = [NSProgress progressWithTotalUnitCount:max];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
for (int i = 0; i < max; ++i) {
localProgress.completedUnitCount++;
[NSThread sleepForTimeInterval:1];
}
});
}
How would you handle this case where you cannot change the becomeCurrentWithPendingUnitCount
since you don't know its weight prior to begin downloading ?
EDIT: This is what I do for now:
First of all: I lied. I don't download files but data from a database, but it's the same problem in the end.
Before creating my root NSProgress
, I download the number of objects from my backend (SELECT count(*) FROM ...
). With this I can call becomeCurrentWithPendingUnitCount
with the correct "weight" and the progress appears more "smooth".
Of course, this is far from ideal for me since I have to wait some time before showing the first NSProgress
, and it makes me do more queries to the backend, but at least the experience is a bit better.
If I could remove this it would be much better. Any ideas?