Objective C: Downloading File with Progress Bar

Objective C: Downloading File With Progress Bar

Using AFNetworking,

here progress is the UIProgressview

#import //add to the header of class

-(void)downloadShowingProgress
{
progress.progress = 0.0;

currentURL=@"http://www.selab.isti.cnr.it/ws-mate/example.pdf";


NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:currentURL]];
AFURLConnectionOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"MY_FILENAME_WITH_EXTENTION.pdf"];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:filePath append:NO];

[operation setDownloadProgressBlock:^(NSUInteger bytesRead, NSUInteger totalBytesRead, NSUInteger totalBytesExpectedToRead) {
progress.progress = (float)totalBytesRead / totalBytesExpectedToRead;

}];

[operation setCompletionBlock:^{
NSLog(@"downloadComplete!");

}];
[operation start];

}

Using NSURLConnection

-(void)downloadWithNsurlconnection
{

NSURL *url = [NSURL URLWithString:currentURL];
NSURLRequest *theRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:60];
receivedData = [[NSMutableData alloc] initWithLength:0];
NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];


}


- (void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
progress.hidden = NO;
[receivedData setLength:0];
expectedBytes = [response expectedContentLength];
}

- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[receivedData appendData:data];
float progressive = (float)[receivedData length] / (float)expectedBytes;
[progress setProgress:progressive];


}

- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

}

- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse: (NSCachedURLResponse *)cachedResponse {
return nil;
}

- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *pdfPath = [documentsDirectory stringByAppendingPathComponent:[currentURL stringByAppendingString:@".mp3"]];
NSLog(@"Succeeded! Received %d bytes of data",[receivedData length]);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[receivedData writeToFile:pdfPath atomically:YES];
progress.hidden = YES;
}

Multiple downloading progress bar objective c

Well...after few days thinking about my issue, I realize I was doing too many database access and because of that my app freeze.
I solved it passing to my HTTPConnection object, an instance of the progress bar I want to manage. And I save the progress download/upload only when finishing.

So that is my solution:

In HTTPConnection:

+ (void)setProgressBar:(UIProgressView *)progress
{
[downloadConnection setProgressBar:progress];
}

//CODE...

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
float progress = (float)totalBytesWritten/(float)totalBytesExpectedToWrite;
if (self.progressBar) {
self.progressBar.progress = progress;
}
if (progress == 1.0) {
[self saveProgressInDatabase:[NSNumber numberWithFloat:progress]];
}
}

And in my message list:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Message *info = [_fetchedResultsController objectAtIndexPath:indexPath];

//MORE CODE...

if (([info contentSize]!=NULL)&&([[info uploaded]floatValue]<1.0)) {
[HTTPConnection setProgressBar:cell.progressBar];
[cell.progressBar setHidden:NO];
} }

Thanks for your help!

Objective c: download a file with progress view

You can get expected total file size in following callback method of NSURLconnection,

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
expectedTotalSize = response.expectedContentLength;
}

then in the following callback method you can calculate how much data has been recieved,

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
recievedData += data.length;
}

And you can use UIProgressView to show current downloading status on the screen.

ProgressView for Downloading some files in Object-C

I think that it is related to threads and how the main thread will refresh the view.

Two cases can occur:

You are on the main thread when calling this method

In such case, you do not allow the main thread to execute refresh routines. Move all this download to a background queue using GCD, and call back the main thread like explained in pt.2.

To put everything in a background queue, you could call:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
// your download code goes here


});

Or, You are already on the background thread, then use the following lines to call back to the main thread:

dispatch_async(dispatch_get_main_queue(), ^ {
progressView.progress = (float)i/(float)7;
});

Final answer:

- (IBAction)download:(id)sender {

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^ {
// Determile cache file path
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

progressSlider.progress = 0.0;

for (i=0;i<=7;i++) {

//Updating progressView and progressLabel
progressLabel.text = [NSString stringWithFormat:@"Загружено: %d из 7",i];
dispatch_async(dispatch_get_main_queue(), ^ {
progressView.progress = (float)i/(float)7;
});

NSString *filePath = [NSString stringWithFormat:@"%@/avto-0-%d.html", [paths objectAtIndex:0],i];

// Download and write to file
NSString *mustUrl = [NSString stringWithFormat:@"http://www.mosgortrans.org/pass3/shedule.php?type=avto&%@", [listOfAvtoUrl objectAtIndex:i]];
NSURL *url = [NSURL URLWithString:mustUrl];
NSData *urlData = [NSData dataWithContentsOfURL:url];


[urlData writeToFile:filePath atomically:YES];
}
});
}

Showing the file download progress with NSURLSessionDataTask

You need to implement following delegates:

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;
}

How can I link a file download with a Progress View

Here is complete working example for you:

import UIKit

class ViewController: UIViewController, NSURLSessionDownloadDelegate {


@IBOutlet weak var progressBar: UIProgressView!
@IBOutlet weak var progressCount: UILabel!

var task : NSURLSessionTask!

var percentageWritten:Float = 0.0
var taskTotalBytesWritten = 0
var taskTotalBytesExpectedToWrite = 0

lazy var session : NSURLSession = {
let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
config.allowsCellularAccess = false
let session = NSURLSession(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
return session
}()

override func viewDidLoad() {
progressBar.setProgress(0.0, animated: true) //set progressBar to 0 at start
}

@IBAction func doElaborateHTTP (sender:AnyObject!) {

progressCount.text = "0%"
if self.task != nil {
return
}

let s = "http://www.qdtricks.com/wp-content/uploads/2015/02/hd-wallpapers-1080p-for-mobile.png"
let url = NSURL(string:s)!
let req = NSMutableURLRequest(URL:url)
let task = self.session.downloadTaskWithRequest(req)
self.task = task
task.resume()

}

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten writ: Int64, totalBytesExpectedToWrite exp: Int64) {
println("downloaded \(100*writ/exp)")
taskTotalBytesWritten = Int(writ)
taskTotalBytesExpectedToWrite = Int(exp)
percentageWritten = Float(taskTotalBytesWritten) / Float(taskTotalBytesExpectedToWrite)
progressBar.progress = percentageWritten
progressCount.text = String(format: "%.01f", percentageWritten*100) + "%"
}

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didResumeAtOffset fileOffset: Int64, expectedTotalBytes: Int64) {
// unused in this example
}

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
println("completed: error: \(error)")
}

// this is the only required NSURLSessionDownloadDelegate method

func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {

let documentsDirectoryURL = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as! NSURL
println("Finished downloading!")
println(documentsDirectoryURL)
var err:NSError?

// Here you can move your downloaded file
if NSFileManager().moveItemAtURL(location, toURL: documentsDirectoryURL.URLByAppendingPathComponent(downloadTask.response!.suggestedFilename!), error: &err) {
println("File saved")
} else {
if let err = err {
println("File not saved.\n\(err.description)")

}
}

}

}

You can use NSURLSessionDownloadDelegate to achieve this whose method will be called when user downloading data.

This will show you the process into progressCount label and the progressBar will show process as count will increment. you can modify this as per your need.

You can download this example from HERE.

how to use the progress bar in the iphone app

first you create IBOutlet in .h file

IBOutlet UIProgressView * threadProgressView;

Then in .m file in viewdidload first set progress to 0.0 and then call makeMyProgressMoving method

    threadProgressView.progress = 0.0;
[self performSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO];

then add below method

- (void)makeMyProgressBarMoving {

float actual = [threadProgressView progress];
if (actual < 1) {
threadProgressView.progress = actual + ((float)recievedData/(float)xpectedTotalSize);
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(makeMyProgressBarMoving) userInfo:nil repeats:NO];
}
else{



}

}

also give your review for answer. is it useful to you?



Related Topics



Leave a reply



Submit