Progress tracking an NSURLSessionDownloadTask using KVO

I have a piece of working code that downloads a file using NSURLDownloadTask, that tracks the download progress using URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:. The progress indicator fill in smoothly - it looks good. I am now refactoring the code to not use session and task delegate methods for various reasons. For progress indication I switched to KVO on the download taks's countOfBytesReceived (the documentation notes that all task properties support key-value observing). It does work, but it looks pretty bad - the intervals between progress incrementation take too long and sometimes never show up at all. To my understanding, I should not explicilty dispatch the task to a background queue - it should be done by the session task itself (or should I?).


Example code follows (please excuse the vintage ObjC syntax...)


- (void)download:(NSURL*)url {
        self.task = [session downloadTaskWithURL:url completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            [self stopObservingProgressChanges];
            // ...
        }];
        [self startObservingProgressChanges];
        [self.task resume];
}


- (void)startObservingProgressChanges {
    __weak WTPackageDownloader *weakSelf = self;
    [self.task addObserver:self
                   keyPath:@"countOfBytesReceived"
                   options:NSKeyValueObservingOptionInitial | NSKeyValueObservingOptionNew
                     block:^(MAKVONotification *notification) {
                         weakSelf.package.progress.totalUnitCount = weakSelf.task.countOfBytesExpectedToReceive;
                         weakSelf.package.progress.completedUnitCount = weakSelf.task.countOfBytesReceived;
                     }];
}


- (void)stopObservingProgressChanges {
    [self.task removeObserver:self keyPath:@"countOfBytesReceived"];
}
Answered by Nimi P in 98357022

OK, problem solved by dispatching the observer block to the main queue.

Accepted Answer

OK, problem solved by dispatching the observer block to the main queue.

Progress tracking an NSURLSessionDownloadTask using KVO
 
 
Q