I use this code to download files. Download animation in progrssView carried out at the last moment. Instead of being implemented during the entire process. How to solve a problem?
Code in my Xcode project:
- (void)viewDidLoad
{
_progressView = [[UIProgressView alloc] initWithProgressViewStyle: UIProgressViewStyleDefault];
_progressView.progressTintColor = [UIColor colorWithRed:0.0/255 green:0.0/255 blue:0.0/255 alpha:0.4];
[[_progressView layer]setFrame:CGRectMake(60, 150, 100, 25)];
[[_progressView layer]setBorderColor:[UIColor whiteColor].CGColor];
_progressView.trackTintColor = [UIColor clearColor];
[_progressView setProgress:(float)(50/100) animated:YES];
[[_progressView layer]setCornerRadius:_progressView.frame.size.width / 8];
[[_progressView layer]setBorderWidth:1];
[[_progressView layer]setMasksToBounds:TRUE];
_progressView.clipsToBounds = YES;
[self.view addSubview:_progressView];
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
[self.progressView setProgress:0 animated:NO];
}
-(IBAction) downloadButton:(id)sender
{
if(_downloadTask == nil){
_url =[NSURL URLWithString:@"http://www.freeiconspng.com/uploads/ios-png-6.png"];
_url1 =[NSURL URLWithString:@"http://www.freeiconspng.com/uploads/ios-png-6.png"];
_downloadTask = [_session downloadTaskWithURL:_url];
_downloadTask = [_session downloadTaskWithURL:_url1];
[_downloadTask resume];
}
else
[_downloadTask resume];
}
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:@"image1.png"];
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:NO];
NSData *urlData = [NSData dataWithContentsOfURL:_url];
[urlData writeToFile:filePath atomically:YES];
NSString *filePath1 = [documentsDirectory stringByAppendingPathComponent:@"image2.png"];
BOOL fileExists1 = [[NSFileManager defaultManager] fileExistsAtPath:filePath1 isDirectory:NO];
NSData *urlData1 = [NSData dataWithContentsOfURL:_url1];
[urlData1 writeToFile:filePath1 atomically:YES];
}
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;{
dispatch_async(dispatch_get_main_queue(), ^{
[self.progressView setProgress:totalBytesWritten/totalBytesExpectedToWrite animated:YES];
});
}
UPD
You mean it?
dispatch_async(dispatch_get_main_queue(), ^{
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:[NSOperationQueue mainQueue]];
});
It doesn’t work.
I add label in
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;{
dispatch_async(dispatch_get_main_queue(), ^{
[self.progressView setProgress:totalBytesWritten/totalBytesExpectedToWrite animated:YES];
_label = [[UILabel alloc]initWithFrame:CGRectMake(91, 15, 500, 50)];
_label.text = [NSString stringWithFormat: @"%lld", totalBytesWritten];
_label.numberOfLines = 1;
_label.backgroundColor = [UIColor blackColor];
_label.textColor = [UIColor whiteColor];
_label.textAlignment = NSTextAlignmentCenter;
[self.view addSubview:_label];
});
}
At download time, the numbers in the label increase. After increase number stopped I see progrssView
animation.
My label https://drive.google.com/file/d/0B0EJbcHq3ZALX0JNLU1iTFA1d2M/view
The code you've posted looks reasonable. You've implemented the URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
delegate method, which should get called as the data comes in for the file. You're setting the progress view from a call to dispatch_async(dispatch_get_main_queue())
, which you should normally do.
One thing I notice is that you create your NSURLSession configuration using [NSOperationQueue mainQueue]
, which will cause your NSURLSession delegate methods to be called on an operation queue that runs on the main thread.
Try passing in nil for the operation queue. You're already protecting your UI code by wrapping it in calls to dispatch_async(dispatch_get_main_queue())
like you should, so the delegate methods should be safe from a background serial queue.
I would also suggest logging the values of totalBytesWritten
and totalBytesExpectedToWrite
within your URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
method to figure out how many times it's being called and with what values.
You show code where you create your NSURLSession from inside a call to dispatch_async:
dispatch_async(dispatch_get_main_queue(), ^{
_session =
[NSURLSession sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:self
delegateQueue:[NSOperationQueue mainQueue]];
});
That makes no sense whatsoever. What I meant was this:
_session =
[NSURLSession sessionWithConfiguration:
[NSURLSessionConfiguration defaultSessionConfiguration]
delegate: self
delegateQueue: nil];
By passing nil for the delegateQueue parameter, your delegate methods will be called from the background.
Also adding a new label every time your delegate method gets called is nuts. Simply use NSLog:
- (void)URLSession:(NSURLSession *)session downloadTask:
(NSURLSessionDownloadTask *) downloadTask
didWriteData:(int64_t) bytesWritten
totalBytesWritten:(int64_t)totalBytesWritten
totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite;
{
NSLog(@"In didWriteData, totalBytesWritten = %l, filesize = %l",
totalBytesWritten,
totalBytesExpectedToWrite);
dispatch_async(dispatch_get_main_queue(), ^
{
[self.progressView setProgress:totalBytesWritten/totalBytesExpectedToWrite
animated:YES];
});
}