views:

1029

answers:

1

I am using this code:

NSURLConnection *oConnection=[[NSURLConnection alloc] initWithRequest:oRequest delegate:self];

to download a file, and I want to update a progress bar on a subview that I load. For that, I use this code:

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [oReceivedData appendData:data];
 float n = oReceivedData.length;
 float d = self.iTotalSize;
 NSNumber *oNum = [NSNumber numberWithFloat:n/d];
 self.oDPVC.oProgress.progress = [oNum floatValue];
}

The subview is oDPVC, and the progress bar on it is oProgress. Setting the progress property does not update the control.

From what I have read on the Web, lots of people want to do this and yet there is not a complete, reliable sample. Also, there is much contradictory advice. Some people think that you don't need a separate thread. Some say you need a background thread for the progress update. Some say no, do other things in the background and update the progress on the main thread.

I've tried all the advice, and none of it works for me.

One more thing, maybe this is a clue. I use this code to load the subview during applicationDidFinishLaunching:

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

In the XIB file (which I have examined in both Interface Builder and in a text editor) the progress bar is 280 pixels wide. But when the view opens, it has somehow been adjusted to maybe half that width. Also, the background image of the view is default.png. Instead of appearing right on top of the default image, it is shoved up about 10 pixels, leaving a white bar across the bottom of the screen.

Maybe that's a separate issue, maybe not.

+2  A: 
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;
Shaggy Frog
I appreciate your remark about double retain-ing. I could stand to know a lot more on that topic.self.oDPVC is not nil because I successfully add its subview to the window.self.oDPVC.oProgress is not nil because I am able to check its width as follows: CGRect newFrame = self.oDPVC.oProgress.frame; NSLog(@"Progress width: %f", newFrame.size.width);Finally, divide by zero isn't an issue since my denominator is the total bytes expected, and that never will be zero.
Scott Pendleton
I should add that when I test the width of oProgress, it is 160, not the 280 as it was set in IB. One more clue about the progress bar: some people report that the progress bar stays at zero and jumps to 100 at the end of whatever their task is. Mine NEVER changes from zero.
Scott Pendleton
All problems are resolved. The default.png had white space under it because in IB it was resized to make room for a status bar, and I didn't know it. The progress bar was the wrong size because somehow I had some code in my viewDidLoad that was init-ing another UIProgressView or re-initing the existing one. Removing that line of code cause the progress bar to be the expected size, plus it updates now and I did not need to fool around with threads. Moral: you always find what you are looking for in the last place that you look!
Scott Pendleton