7

Summary: I want to track the progress of file downloads with progress bars inside cells of a tableview. I'm using ASIHTTPRequest in an ASINetworkQueue to handle the downloads.
It works, but the progress bars stay at 0%, and jump directly at 100% at the end of each download.


Details: I set up my ASIHTTPRequest requests and ASINetworkQueue this way:

[Only an extract of my code]

- (void) startDownloadOfFiles:(NSArray *) filesArray {

    for (FileToDownload *aFile in filesArray) {

        ASIHTTPRequest *downloadAFileRequest = [ASIHTTPRequest requestWithURL:aFile.url];

        UIProgressView *theProgressView = [[UIProgressView alloc] initWithFrame:CGRectMake(20.0f, 34.0f, 280.0f, 9.0f)];
        [downloadAFileRequest setDownloadProgressDelegate:theProgressView];

        [downloadAFileRequest setUserInfo:
            [NSDictionary dictionaryWithObjectsAndKeys:aFile.fileName, @"fileName",
                                                        theProgressView, @"progressView", nil]];
        [theProgressView release];

        [downloadAFileRequest setDelegate:self];
        [downloadAFileRequest setDidFinishSelector:@selector(requestForDownloadOfFileFinished:)];
        [downloadAFileRequest setDidFailSelector:@selector(requestForDownloadOfFileFailed:)];
        [downloadAFileRequest setShowAccurateProgress:YES];

        if (! [self filesToDownloadQueue]) {
            // Setting up the queue if needed
            [self setFilesToDownloadQueue:[[[ASINetworkQueue alloc] init] autorelease]];

            [self filesToDownloadQueue].delegate = self;
            [[self filesToDownloadQueue] setMaxConcurrentOperationCount:2];
            [[self filesToDownloadQueue] setShouldCancelAllRequestsOnFailure:NO]; 
            [[self filesToDownloadQueue] setShowAccurateProgress:YES]; 

        }

        [[self filesToDownloadQueue] addOperation:downloadAFileRequest];
    }        

    [[self filesToDownloadQueue] go];
}

Then, in a UITableViewController, I create cells, and add the name of the file and the UIProgressView using the objects stored in the userInfo dictionary of the request.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"fileDownloadCell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"FileDownloadTableViewCell" owner:self options:nil];
        cell = downloadFileCell;
        self.downloadFileCell = nil;
    }

    NSDictionary *userInfo = [self.fileBeingDownloadedUserInfos objectAtIndex:indexPath.row];

    [(UILabel *)[cell viewWithTag:11] setText:[NSString stringWithFormat:@"%d: %@", indexPath.row, [userInfo valueForKey:@"fileName"]]];

    // Here, I'm removing the previous progress view, and adding it to the cell
    [[cell viewWithTag:12] removeFromSuperview];
    UIProgressView *theProgressView = [userInfo valueForKey:@"progressView"];
    if (theProgressView) {
        theProgressView.tag = 12;
        [cell.contentView addSubview:theProgressView];
    } 


    return cell;
}

The progress bar are all added, with the progress set to 0%. Then, at end of download, they instantly jump to 100%.

Some of the download are very big (more than 40Mb).

I do not do anything tricky with threads.

Reading the forums of the ASIHTTPRequest, it seems I'm not alone, but I couldn't find a solution. Am I missing something obvious? Is this a bug in ASI* ?

Guillaume
  • 21,685
  • 6
  • 63
  • 95

1 Answers1

6

ASIHTTPRequest can only report progress if the server is sending Content-Length: headers, as otherwise it doesn't know how big the response will be. (ASINetworkQueue also sends HEAD requests at the start to try to figure out document sizes.)

Try collecting all the network traffic with charlesproxy or wireshark, see if these headers are present and/or what is happening with the HEAD requests.

JosephH
  • 37,173
  • 19
  • 130
  • 154
  • Progress bar was working when I was not using ASINetworkQueue, only ASIHTTPRequests. So I assume headers are ok. Will verify with network sniffing. – Guillaume Jul 01 '11 at 09:54
  • In the headers, I do not have the Content-Length info. Is this possible the progress of ASIHTTPRequests was working with the same server when not using a queue? I asked the web developer to change the headers sent. Will see how it goes. – Guillaume Jul 01 '11 at 10:17
  • I'm not sure if that's possible. Only way to know for sure would be to try your previous code and check the headers there too. – JosephH Jul 01 '11 at 10:25
  • Headers sent by server fixed: it now works. Thank you for giving me the right perspective on this issue. – Guillaume Jul 04 '11 at 08:33