1

I am using ASIHTTPRequest to download a file locally to the iDevice.

My download code is as follows

ASIHTTPRequest *download = [ASIHTTPRequest requestWithURL: videoUrl];
[download setCompletionBlock:^{            
    NSLog(@"Download Success");        
    // other code
}];
[download setFailedBlock:^{            
    NSLog(@"Download Failed");
    // other code
}];
[download setDownloadProgressDelegate: [item progressDelegate]];
[download startAsynchronous];
NSLog(@"Start Download of %@", [item name]);

The object item holds a reference to a UIProgressView It is show on the screen but never updated.

In an attempt to debug, I subclassed UIProgressView and added the following log

- (void)setProgress:(float)newProgress {        
  NSLog(@"Current Progress : %f", newProgress);
  [super setProgress: newProgress];
}

My Console now shows the progress going from 0.0 to 1.0 over ~50 iterations (nice!) but the uiProgressView doesnt change and at the end the NSLog show 0.5 the default setting for the progress view.

Anyone have an Idea what is happening?

EDIT UIProgressView is accessed with this

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
   UITableViewCell *cell = [tableView cellForRowAtIndexPath: indexPath];
   id progressView = [cell viewWithTag:VideoDetailProgressView];
   [VideoDownloadManager queueDownloadOfVideo:video progressDelegate: progressView];
}

I have stepped through and watched it appears to keep the correct reference to the UIProgressView throughout

Edit TableView Methods

 // Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier:
 // Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls)
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *detailCellIdentifier = @"VideoDetailCell";
static NSString *categoryCellIdentifier = @"VideoCategoryCell";
UITableViewCell *cell = nil;
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:@"parentName"];


if(isCategorical)
{
    cell = [tableView dequeueReusableCellWithIdentifier:categoryCellIdentifier];
}
else
{
    cell = [tableView dequeueReusableCellWithIdentifier:detailCellIdentifier];
}

if (cell == nil && !isCategorical) {
    [[NSBundle mainBundle] loadNibNamed:@"VideoDetailCell" owner:self options:nil];
    cell = self.videoDetailCell;


    UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5.0, 10.0, 46.0, 46.0)];
    [cell addSubview:imageView];
    imageView.hidden = !self.canEdit;
    imageView.tag = VideoDetailsFavoriteButton;
    [imageView release];        


    self.videoDetailCell = nil;
}
else if(cell == nil && isCategorical)
{
    //Different cell
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:categoryCellIdentifier] autorelease];
}
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}



// Display customization
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *object = [self.videoList objectAtIndex:indexPath.row];
bool isCategorical = [[self.videoList objectAtIndex: indexPath.row] objectForKey:@"parentName"];

if(isCategorical) {
    cell.textLabel.textColor = [UIColor whiteColor];
    cell.textLabel.text = [object objectForKey:@"name"];

    NSUInteger videoCount = [[Videos sharedVideos] countById: [object objectForKey:@"name"]];
    cell.detailTextLabel.textColor = [UIColor whiteColor];
    cell.detailTextLabel.text = [NSString stringWithFormat: @"%d videos", videoCount];
}
else
{
    [[cell viewWithTag:VideoDetailCellTitle] setValue:[object objectForKey:@"name"] forKey:@"text"];
    [[cell viewWithTag:VideoDetailCellSubtitle] setValue:[object objectForKey:@"dateAdded"] forKey:@"text"];
    [[cell viewWithTag:VideoDetailCellDuration] setValue:[object objectForKey:@"duration"] forKey:@"text"];

    UIHTTPImageView *asyncImage = (UIHTTPImageView *)[cell viewWithTag:VideoDetailCellImage];
    NSURL *thumbUrl = [NSURL URLWithString:[NSString stringWithFormat: @"%@%@", kRootUrlPath, [object objectForKey:@"image"]]];
    [asyncImage setImageWithURL:thumbUrl placeholderImage: [UIImage imageNamed: kLoadingImage]];
    asyncImage.clipsToBounds = YES;

    UIImageView *editButton = (UIImageView *)[cell viewWithTag:VideoDetailsFavoriteButton];

    if ([VideoDownloadManager isQueued: [object objectForKey: @"name"]]) {
        [[cell viewWithTag:VideoDetailCellSubtitle] setHidden:YES];
        [[cell viewWithTag:VideoDetailProgressView] setHidden:NO];
    } else {
        [[cell viewWithTag:VideoDetailCellSubtitle] setHidden:NO];
        [[cell viewWithTag:VideoDetailProgressView] setHidden:YES];
    }

    if ([VideoDownloadManager isFavorites: [object objectForKey: @"name"]] || [VideoDownloadManager isQueued: [object objectForKey: @"name"]]) {
        editButton.image = [UIImage imageNamed: kFavoritesHighlighted];  
    } else {
        editButton.image = [UIImage imageNamed: kFavoritesEmpty];  
    }

 }
}
Bill Bonar
  • 1,017
  • 2
  • 10
  • 22
  • That's an odd one :) You don't have two UIProgressViews do you; one created in a xib (but not connected to an IBOutlet) and one created in code (your `progressDelegate`) ? – deanWombourne Jan 04 '12 at 17:32
  • For a second, I thought I missed something stupid simple but also no. The UIProgressView (or my subclass) is created on the xib. I access using `viewWithTag` so there should not be an issue with it there. – Bill Bonar Jan 04 '12 at 17:38
  • What do you get if you add `NSLog("%@", [self superview]);` in your progress bar subclass's `setProgress:` method? And maybe @Dirty Harrys answer is onto something (though I suspect not because ASI _should_ always perform callbacks on the main thread). – deanWombourne Jan 04 '12 at 17:41
  • ok we are getting somewhere, `[self superview]` is `null` But i am not sure how that could be – Bill Bonar Jan 04 '12 at 17:48
  • Answer your own question with your solution and mark it as acccepted ;) – deanWombourne Jan 04 '12 at 21:25

2 Answers2

0

Can you check if the update is made in the main thread? (it should be the case if you're using the latest version of ASIHTTPRequest)

NSLog(@"Current Progress : %f (main thread=%d)", newProgress, [NSThread isMainThread]);

If it doesn't help, can you show the code that is using the UIProgressView in the view?

Mick F
  • 7,312
  • 6
  • 51
  • 98
  • that's a good start, i think we need some view management code to help you now, as also mentioned by @deanWombourne – Mick F Jan 04 '12 at 17:46
  • I think, the problem relies on the fact that you keep the progress view in a cell rather than in the view controller => if you scroll down, that your cell disappears and reappears, you'd lose the progress view. So I'm not sure what your problem is here, but you have a design problem. You should store a dictionary of progress view with a key referencing the video you're handling in the cell, create it and display it in didSelectRowAtIndexPath: but also handling it in cellForRowAtIndexPath: – Mick F Jan 04 '12 at 17:54
  • (your question edit helped, that was what I wanted to see) :) – Mick F Jan 04 '12 at 17:57
  • That may make sense but I am not scrolling. And the log shows the object has been dealloc yet right ? – Bill Bonar Jan 04 '12 at 17:58
  • Can you show us your cellForRowAtIndexPath: method too then? :) – Mick F Jan 04 '12 at 18:00
0

Thanks for everyones help. You guys guided me to then answer. My cell was not correctly being assigned a reuseIdentifier

this was causing the whole issue.

Bill Bonar
  • 1,017
  • 2
  • 10
  • 22