Showing the file download progress with NSURLSessionDataTask

swift download file with progress
swift download file with progress github
nsurlsessiondownloadtask
nsurlsession background download
ios download file from url
nsurlsession in swift
nsurlsession tutorial
nsurlsession(configuration swift)

I want to display file download progress (how many bytes are received) of particular file. It works fine with the NSURLSessionDownloadTask .My question is I want to achieve the same with the NSURLSessionDataTask.

Here is the code which receives file into NSData and writes to document folder:

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];

NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];

NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithURL:theRessourcesURL
    completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{ 
       if(error == nil)
       {

            NSString *docsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

               NSString *pathToDownloadTo = [NSString stringWithFormat:@"%@/%@", docsDir, Name];

               NSLog(@"SIZE : %@",[NSByteCountFormatter stringFromByteCount:data.length countStyle:NSByteCountFormatterCountStyleFile]);

               [data writeToFile:pathToDownloadTo options:NSDataWritingAtomic error:&error];
       }
}];

[dataTask resume];

I am getting file size after write or complete datatask (after the file is received) :

NSLog(@"SIZE : %@",[NSByteCountFormatter stringFromByteCount:data.length countStyle:NSByteCountFormatterCountStyleFile]);

But i want to display it's current bytes received status, is this possible with NSURLSessionDataTask?

You need to implement following delegates:

<NSURLSessionDataDelegate, NSURLSessionDelegate, NSURLSessionTaskDelegate>

Also need to create two properties:

@property (nonatomic, retain) NSMutableData *dataToDownload;
@property (nonatomic) float downloadSize;

- (void)viewDidLoad {
    [super viewDidLoad];

    NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];

    NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue]];

    NSURL *url = [NSURL URLWithString: @"your url"];
    NSURLSessionDataTask *dataTask = [defaultSession dataTaskWithURL: url];

    [dataTask resume];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
    completionHandler(NSURLSessionResponseAllow);

    progressBar.progress=0.0f;
    _downloadSize=[response expectedContentLength];
    _dataToDownload=[[NSMutableData alloc]init];
}

- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
    [_dataToDownload appendData:data];
    progressBar.progress=[ _dataToDownload length ]/_downloadSize;
}

download progress NSURLSession – iOS Cheat sheet, This example downloads a sample zip file and it is implemented using NSURLSession delegates. There is another approach where you can use blocks​  7 Downloading more than one file Using NSURLSession and also maintain their progress in background state Mar 3 '14 6 Showing the file download progress with NSURLSessionDataTask Jun 2 '14 5 Record the sound and play it back with changed pitch May 11 '12

You can also use NSURLSessionDownloadTask like following. Call startDownload methode.In .h file use this

- (void)startDownload
{
    NSString *s;
    s = @"http://www.nasa.gov/sites/default/files/styles/1600x1200_autoletterbox/public/pia17474_1.jpg?itok=4fyEwd02";
    NSURLSessionDownloadTask *task = [self.session downloadTaskWithURL:[NSURL URLWithString:s]];
    [task resume];
}

- (NSURLSession *) configureSession {
    NSURLSessionConfiguration *config =
    [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.neuburg.matt.ch37backgroundDownload"];
    config.allowsCellularAccess = NO;
    // ... could set config.discretionary here ...
    NSURLSession *session = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:[NSOperationQueue mainQueue]];
    return session;
}

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite {
    CGFloat prog = (float)totalBytesWritten/totalBytesExpectedToWrite;
    NSLog(@"downloaded %d%%", (int)(100.0*prog));

}

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didResumeAtOffset:(int64_t)fileOffset expectedTotalBytes:(int64_t)expectedTotalBytes {
    // unused in this example
}

-(void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
    NSData *d = [NSData dataWithContentsOfURL:location];
    UIImage *im = [UIImage imageWithData:d];
    dispatch_async(dispatch_get_main_queue(), ^{
        self.image = im;

    });
}

-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
    NSLog(@"completed; error: %@", error);
}

Downloading Files from Websites, To download files, you create an NSURLSessionDownloadTask from an Create your own NSURLSession instance, and set its delegate property. fractional progress of the download, and uses it to update a label that shows progress as a  In iOS NSURLSession Example, I have explained how use NSURLSession API to make HTTP requests.NSURLSession class is introduced in iOS 7 and OS X v10.9.NSURLSession is replacement for NSURLConnection and this API gives your app the ability to perform background downloads when your app is in background.

Since iOS 11.0 and macOS 10.13, URLSessionTask (former NSURLSessionTask) adopted the ProgressReporting protocol. That means you can use the progress property to track the progress of a session task.

Expecting you already know how to use KVO observers, you can do something like:

task = session.downloadTask(with: url)
task.resume()
task.progress.addObserver(self, forKeyPath: "fractionCompleted", options: .new, context: &self.progressKVOContext)

and observe the value with:

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    if context == &self.progressKVOContext, let keyPath = keyPath {
        switch keyPath {
        case "fractionCompleted":
            guard let progress = object as? Progress else {
                return
            }
            DispatchQueue.main.async { [weak self] in
                self?.onDownloadProgress?(progress.fractionCompleted)
            }
        case "isCancelled":
            cancel()
        default:
            break
        }
    }
    else {
        super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
    }
}
iOS 13 update

OperationQueue has now a progress property.

For example, the UIProgressView can observe that property and update the progress value automatically using the observedProgress. Full example in https://nshipster.com/ios-13/#track-the-progress-of-enqueued-operations.

Tracking Download Progress With Swift, I want to display file download progress (how many bytes are received) of particular file. It works fine with the NSURLSessionDownloadTask .My question is I  I want to display file download progress (how many bytes are received) of particular file. It works fine with the NSURLSessionDownloadTask .My question is I want to achieve the same with the NSURLSessionDataTask.

import Foundation
import PlaygroundSupport

let page = PlaygroundPage.current
page.needsIndefiniteExecution = true

let url = URL(string: "https://source.unsplash.com/random/4000x4000")!
let task = URLSession.shared.dataTask(with: url) { _, _, _ in
  page.finishExecution()
}

// Don't forget to invalidate the observation when you don't need it anymore.
let observation = task.progress.observe(\.fractionCompleted) { progress, _ in
  print(progress.fractionCompleted)
}

task.resume()

Programming IOS 7, project, which streams ma4 music files from Apple's iTunes Preview API. To start with, let's go over monitoring the progress of a download. The NSURLSession API involves many different classes working together in a  I’m trying to download a large file. It’s not showing up in downloads at all but when I try to close Edge, I get a pop-up saying I’m currently downloading a file and that will stop if I close the browser. Is there any other way to see progress? Thanks!

iOS - Objective-C, Here, then, is my recasting ofthe same image file download as in the previous Since one NSURLSession can perform multiple tasks, there will typically be just use the task instance variable as a flag to indicate that the task is in progress. Edge and download progress. Hewjr100. Posts : 519. Windows 10 Pro New 27 Sep 2017 #1. Edge and download progress. Edge in PC allows file download. On my laptop

How you would use NSURLSession to download files, Now the way, NSURLSession works, is that it downloads your file directly to which is great for notifying your users of the download progress:. NSURLSessionDataTask : It is mainly used to read simple data on the server side, such as JSON data. NSURLSessionDownloadTask: The main purpose of this task is to download files. It does more processing for large file network requests, such as download progress, break point continuation, and so on.

Programming IOS 9: Dive Deep Into Views, View Controllers, and , The progress view will be useful to show you the progress of the download task as bytes are being downloaded. Your view will look something  If you want to make a file in `External Storage` becomes visible in Picture, Downloads, or other built-in apps, you will have to use `Media Scanner` or `Download Manager`. 10 ios/RNFetchBlobNetwork.m

Comments
  • Thankyou so much for your replay but now problem is this both method not called when i am download file i added delegate and used same above code.
  • I have posted another answer please see.
  • @KiranPatel i have changed the code plz have a look a tit and let me know if it works. thanks.:)
  • WAW! Amazing @ Bullet Raja, Thankyou so much you have solved my problem in minuets i am trying to achieve this since last 2 days. Again thankyou. It works like charm...
  • I'm not sure about it. Firstly, they state in the documentation that "As the data may be discontiguous, you should use [NSData enumerateByteRangesUsingBlock:] to access it.". Secondly, it's missing the information how to know the downloading is finished.
  • Above code working perfectly thanks. But i want to achieve this same functionality with NSURLSessionDataTask instead of NSURLSessionDownloadTask. Does it possible ?
  • Sure, No problem please take your time.
  • Any chance could include Objective-C example?