2

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?

Jonas Schmid
  • 5,360
  • 6
  • 38
  • 60

0 Answers0