Question

I have an app that downloads a picture from a server. I would like to show the progress to the user. I have read about UIProgressView on the apple docs and read many answers on this site but I can't get it to work. Here is my code In my viewDidLoad I have

_profileProgressView.hidden= YES;
_profileProgressView.progress = 0.0;

In my - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response I show the UIProgressView and then get the expected size of the image.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
      self.profileProgressView.hidden= NO;
      [self.remote_response setLength:0];
      received = 0;
      self.filesize = [NSNumber numberWithLongLong:[response expectedContentLength]];
      NSLog(@"Content Length::%@", self.filesize);
  }

In my - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d, I calculate the percentage of the image downloaded and then update the progress of the UIProgressView and log the download progress.

 - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
        [self.remote_response appendData:d];

        NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[self.remote_response length]];
        dispatch_async( dispatch_get_main_queue(), ^ {
              float progress = (_profileProgressView.progress + ([self.filesize floatValue]/[resourceLength floatValue])*100);
              [self.profileProgressView setProgress:progress animated:YES];
              NSLog(@"Downloading %.0f%% complete", _profileProgressView.progress);
        });
   }

When I run this code

  1. The UIProgressView never shows up

  2. The log I get is Downloading 0% complete. I expected to get the log of the image being downloaded.

Also I thought I should alloc and init the UIProgressView in the viewDidDownload, when I do that I get UIProgressView but it does not show the progress and it does not hide after the image is done being downloaded.

Was it helpful?

Solution

I think you are over complicating the math with boxing and unboxing of datatypes with NSNumber.

What I would do is create three variables:

double fileLength;
double lastProgress;
double currentLength;

Then do simple math:

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
  fileLength = [response expectedContentLength];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
  double length = [d length];
  currentLength += length;
  double progress = currentLength/fileLength;

  if (lastProgress < progress) {
    profileProgressView.progress = progress;
    lastProgress = progress;
  }
}

OTHER TIPS

I too experienced the same issue before. In this case, we couldnt show accurate progress view. In order to show accurate progress, your server should provide the bytes sent in the response headers. Then oly, u can be able to get the exact data in your connection:didReceiveData: delegate. Or else, u 'll get 1.0 instantly.

Even if you want to show progress view in this case without server dependancy, you can achieve it by splitting your data's length into n steps and use NSTimer to progress it.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top