Set the progress to UIProgressView when upload wit

2019-02-25 09:55发布

问题:

I'm trying to refresh the progress bar in an UIProgressView for an upload request with NSURLConnection. The goal is to refresh the progress bar while uploading a picture. After several searches, I managed to use the didSendBodyData of my connection delegate to check the progress like this :

- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite
{
    if([self.delegate respondsToSelector:@selector(progressView)])
    {
        self.delegate.progressView.progress = (totalBytesWritten / totalBytesExpectedToWrite) * 100.0;
    }
}

Everything works fine, but the problem is that this method is only called one time... So the bar stay at 0% for a moment, then go instantly to 100% without intermediate. I tried (with iOS6 develloper tool on iPhone) to set my connection to a slow edge connection to figure if it is just my upload that is too fast, but no, the upload take a while at 0, then go to 100% instantly and the method is called only one time...

Any idea please ? Thank you ! I can't figure how to fix that...

回答1:

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.