coarse granularity can be a good thing
Posted by matt, Fri Jan 18 23:34:00 UTC 2008
Every so often a bug comes along that ends up being a pain to get around. Unfortunately there are even those out there which have very little documentation on the correct use of the api required. So, many days were spent devouring internet sources for any and all documentation on NSURLDownload. All I could find though was sparse bits of open source code and apples documentation. The open source code is usually a gold mine for figuring out what I wanted, but alas that wasn't the case. The code was either undocumented or so convoluted that following it would be a week long effort of itself.
So, I turned to the Cocoa development lists provided by Apple. These guys are top notch in the majority of cases and often rather helpful. In this case, not many of them had the expertise in using the api calls I was. This then caused me to be left with playing around on my own.
Having some experience with Mathematics, I placed in that part to get what I wanted. This though caused values which were often ridiculous. I couldn't figure out why. I even went to the extent of making the method thread safe so that values weren't overwritten. This though proved to be futile.
My second attempt at fixing it was to place in if statements so that the value was reset after a certain time interval. This still proved the same results.
So, what was wrong?
I then thought that I should, just for the fun of it, see the values that I'm actually getting back from the method. And this is where I found the problem to be. The values that I was getting were very close to zero. They were that small.
So, as it happens when you divide a large number (number of bytes received) by a small number (time between packets received) you get something that is ridiculous. It all started to make sense. I was doing the calculations way too fast. This became a relief and I could simply place in an if statement that delayed the calculation until the duration was longer than one second.
Now since there is very little documentation of calculating the rate of a download I will place in the required method here.
- (void)download:(NSURLDownload *)download didReceiveDataOfLength:(unsigned)length
{
bytesReceived += length;
tempBytesReceived += length;
[self setPercentageComplete:[[NSNumber alloc] initWithDouble:((bytesReceived / (double)expectedLength) * 100.0)]];
duration = [lastPacketReceived timeIntervalSinceNow] * -1;
if(duration > 1) {
bytesPerSecond = tempBytesReceived / duration;
kilobytesPerSecond = bytesPerSecond / 1024;
tempBytesReceived = 0;
lastPacketReceived = [NSDate date];
}
}
God bless,
Matt.