How to Integrate Nsurlconnection with Uiprogressview

How to integrate NSURLConnection with UIProgressView?

Not sure what I'm missing here, but your filesize being -1 seems to be your problem. The API docs clearly state that expectedContentLength may not be available and that NSURLResponseUnknownLength is returned in these cases. NSURLResponseUnknownLength is defined as:

#define NSURLResponseUnknownLength ((long long)-1)

In these cases, you cannot get an accurate progress. You'll need to handle this and display an indeterminate progress meter of some sort.

Add UIProgressView to a NSURLConnection?

In your didReceiveResponse function you could get the total filesize like so -

_totalFileSize = response.expectedContentLength;.

In your didReceiveData function you can then add up to a total bytes received counter -

_receivedDataBytes += [data length];

Now in order to set the progressbar to the correct size you can simply do -

MyProgressBar.progress = _receivedDataBytes / (float)_totalFileSize

(either in the didReceiveData function or somewhere else in your code)

Don't forget to add the variables that hold the number of bytes to your class!

Here's how you could implement the delegates in order to update progressview

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
_totalFileSize = response.expectedContentLength;
responseData = [[NSMutableData alloc] init];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
_receivedDataBytes += [data length];
MyProgressBar.progress = _receivedDataBytes / (float)_totalFileSize;
[responseData appendData:data];
}

I hope this helps..

Add NSURLConnection loading process on UIProgressView

In your didReceiveResponse function you could get the total filesize like so:
_totalFileSize = response.expectedContentLength;.

In your didReceiveData function you can then add up to a total bytes received counter:
_receivedDataBytes += [data length];

Now in order to set the progressbar to the correct size you can simply do:
MyProgressBar.progress = _receivedDataBytes / (float)_totalFileSize

(either in the didReceiveData function or somewhere else in your code)

Don't forget to add the variables that hold the number of bytes to your class!

I hope this helps..

EDIT: Here's how you could implement the delegates in order to update progressview

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
_totalFileSize = response.expectedContentLength;
responseData = [[NSMutableData alloc] init];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
_receivedDataBytes += [data length];
MyProgressBar.progress = _receivedDataBytes / (float)_totalFileSize;
[responseData appendData:data];
}

Set the progress to UIProgressView when upload with NSURLConnection

You should really read a C tutorial on numerical types. Presumably both totalBytesWritten and totalBytesExpectedToWrite are an integer type, so dividing them will result in truncation - that is, the fractional part of the result will be gone. Unless the result is at 100%, the integral part is always 0, so all those divisions will result in zero. Try casting one or both of the variables to float or double to get sensible results.

Also, UIProgressView doesn't accept values between 0 and 100 by default but between 0 and 1. All in all, you should write

self.delegate.progressView.progress = ((float)totalBytesWritten / totalBytesExpectedToWrite);

and it should work fine.

Edit: the problem was that the data you were trying to upload was too small and it didn't need to be broken down to smaller chunks, so it was necessary to call this method only once. If you supply a great amount of data, then it will be able to be sent only in separate pieces, so the progress handler callback will be called multiple times.

NSURLConnection didSendBodyData progress

You have to cast the bytesWritten and the bytesExpected as float values to divide.

float myProgress = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
progressView.progress = myProgress;

Otherwise you are will get either a 0 or some other number as a result of dividing 2 integers.

ie: 10 / 25 = 0

10.0 / 25.0 = 0.40

Objective-C provides the modulus operator % for determining remainder and is useful for dividing integers.

Update iPhone UIProgressView during NSURLConnection download

self.oDPVC.oProgress.progress = [oNum floatValue];

Setting the progress property does not
update the control.

What is the value of self.oDPVC (is it nil)?

What is the value of self.oDPVC.oProgress (is it nil)?

A couple of other points.

First:

self.oDPVC = [[DownloadProgressViewController alloc] initWithNibName:@"DownloadProgressViewController"bundle:nil];

How is your oDPVC @property defined? If it uses retain, this line could (will) later result a memory leak (it will be double retain-ed). You should use this pattern instead:

DownloadProgressViewController* dpvc = [[DownloadProgressViewController alloc] initWithNibName:@"DownloadProgressViewController" bundle:nil];
self.oDPVC = dpvc;
[dpvc release];

Second:

float n = oReceivedData.length;
float d = self.iTotalSize;
NSNumber *oNum = [NSNumber numberWithFloat:n/d];
self.oDPVC.oProgress.progress = [oNum floatValue];

The progress property is a float itself. You don't really need to use an NSNumber object. You also might want to consider adding one to the denominator to avoid divide-by-zero:

float n = oReceivedData.length;
float d = self.iTotalSize;
float percentCompleted = n/(d + 1.0f);
self.oDPVC.oProgress.progress = percentCompleted;

How to use UIProgressView while loading of a UIWebView?

UIWebView doesn't give you any progress information in the normal mode. What you need to do is first fetch your data asynchronously using an NSURLConnection.
When the NSURLConnection delegate method connection:didReceiveResponse, you're going to take the number you get from expectedContentLength and use that as your max value. Then, inside the delegate method connection:didReceiveData, you're going to use the length property of the NSData instance to tell you how far along you are, so your progress fraction will be length / maxLength , normalized to between 0.0 and 1.0.

Finally, you're going to init the webview with data instead of a URL (in your connection:didFinishLoading delegate method).

Two caveats:

  1. It is possible that the expectedContentLength property of the NSURLResponse is going to be -1 (NSURLReponseUnknownLength constant). In that case, I would suggest throwing up a standard UIActivityIndicator that you shut off inside connection:didFinishLoading.

  2. Make sure that any time you manipulate a visible control from one of the NSURLConnection delegate methods, you do so by calling performSelectorOnMainThread: - otherwise you'll start getting the dreaded EXC_BAD_ACCESS errors.

Using this technique, you can show a progress bar when you know how much data you're supposed to get, and a spinner when you don't know.

UIProgressView does not show up

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


Related Topics



Leave a reply



Submit