NSURLSessionDownloadTask progress callback is not smoothly?

726 views Asked by At

I download a file by NSURLSessionDownloadTask in foreground, and I need to show the current download speed in the UI,

but I found that the delegate method:URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite: is not be called smoothly: enter image description here

so I can show the accurate current download speed.

I make sure this is not caused by the server. when I download the same file via ASIHTTPRequest, it's OK, the progress block was called smoothly.

Anyone knows WHY? Thanks!

UPDATE #0:

The delegate method's implementation:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask
      didWriteData:(int64_t)bytesWritten
 totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    _totalReceived += bytesWritten;
    NSLog(@"receive: %8.2f KB, total receive: %8.2f KB", bytesWritten / 1024.f,  _totalReceived / 1024.f);
    CFTimeInterval now = CFAbsoluteTimeGetCurrent();
    if (_lastDataReceiveAt > 0.f) {
        CFTimeInterval delta = now - _lastDataReceiveAt;
        NSLog(@"downloadtask: %p, speed: %8.2f KB/s; avg: %8.2f KB/s; delta time: %3.2fs",
              downloadTask,
              bytesWritten / 1024 / delta, _totalReceived / 1024 / (now - _beginsAt),
              delta);
    }
    _lastDataReceiveAt = now;

    //NSLog(@"downloading ... %.2f%%", totalBytesWritten * 100.f / totalBytesExpectedToWrite);
}

UPDATE #1:

Hi, @Rob, Here is my session installation code:

- (NSURLSession *)sessionWithIdentifier:(NSString *)identifier {
    if (identifier == nil) {
        NSString *bundleId = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"];
        identifier = [NSString stringWithFormat:@"%@:///Downloader#%ld", bundleId, time(NULL)];
    }

    NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
    //config.protocolClasses = @[ASIURLProtocol.class];
    return [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
}

And, the download task initialize:

_session = [self sessionWithIdentifier:nil];
NSURL *url = ...;
_task = [_session downloadTaskWithURL:url];
[_task resume];

CFTimeInterval now = CFAbsoluteTimeGetCurrent();
_beginsAt = now;
_lastDataReceiveAt = now;
_totalReceived = 0;
1

There are 1 answers

7
George Green On

What do you mean by smoothly here? That they are not called at equal time intervals? This is expected.

All you need to do is keep track of the start time and in the call back calculate the speed from the elapsed time and the data received.

If this is not the issue, please provide more code, perhaps the delegate method implementation and what produces these logs. Maybe also what you would like the logs to be?