Note that there are some explanatory texts on larger screens.

plurals
  1. PONSURLResponse Content-Length mismatch size of actual data when running concurrent downloads
    primarykey
    data
    text
    <p>I have a UITableView, when a cell is selected, I make a service call to asynchronously download a PDF file from a web service. It works great, until you select multiple cells directly after one-another (individually), then things start going south..</p> <p>Here's some (stripped down) code to clarify:</p> <p><strong>Inside MasterViewController.m:</strong></p> <pre><code>- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { //To uniquely identify this field, I build a simple string using the indexPath. NSString *key = [[NSString alloc]initWithFormat:@"%d.%d",pIndex.section,pIndex.row]; //Use a pre-populated NSDictionary to specify the file I want from the server. NSString *reportID = [reportDictionary valueForKey:key]; NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/RequestReportWithID",myConnectionObject.ServiceURL]]; NSMutableDictionary *body = [[NSMutableDictionary alloc] initWithObjectsAndKeys:reportID, @"reportID", nil]; NSData *requestData = [NSJSONSerialization dataWithJSONObject:dic options:0 error:nil]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; [request setValue:[NSString stringWithFormat:@"%d", [requestData length]] forHTTPHeaderField:@"Content-Length"]; [request setHTTPBody: requestData]; //Create a new object as delegate to receive the data, also add the key to assist with identification. ReportDownloader *newReportDownloader = [[ReportDownloader alloc]initWithDelegate:self andKey:key]; NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:newReportDownloader]; if (connection) { //Nothing to do here, request was made. } } </code></pre> <p><strong>Inside ReportDownloader.m:</strong></p> <pre><code>long long expectedReportSize; NSString *key; NSData *thisReport; -(NSObject*)initWithDelegate:(NSObject*)pDelegate andKey:(NSString*)pKey { myTypedDelegate = (MasterViewController*)pDelegate; Key = pKey; return self; } - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { expectedReportSize = [response expectedContentLength]; NSLog(@"Key:%@, Expected Size=%lld bytes",Key, [response expectedContentLength]); thisReport = [[NSMutableData alloc] init]; } - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { [thisReport appendData:data]; } - (void)connectionDidFinishLoading:(NSURLConnection *)connection { //Here is where things go wrong... NSLog(@"Key:%@, Actual Size=%ld bytes",Key, (unsigned long)[thisReport length]); } </code></pre> <p>The above code works fine for a single report. And on a fast line, it works fine for 3-4 reports, but try to do more than that and the Expected length starts mismatching the Actual length. And I can't understand whyyyyy....</p> <p>See the output generated by the code above: <em>(Notice that only the report for indexPath 1.1 was downloaded correctly)</em></p> <pre><code>Key:1.0, Expected Size=304006 bytes Key:1.3, Expected Size=124922 bytes Key:1.0, Actual Size=369494 bytes Key:1.3, Actual Size=380030 bytes Key:1.2, Expected Size=179840 bytes Key:1.4, Expected Size=377046 bytes Key:1.2, Actual Size=114376 bytes Key:1.5, Expected Size=175633 bytes Key:1.4, Actual Size=180558 bytes Key:1.5, Actual Size=274549 bytes Key:1.1, Expected Size=443135 bytes Key:1.1, Actual Size=443135 bytes </code></pre> <p>The data corruption is confirmed when trying to open the PDF documents, which fail for all file's who's data size didn't match the expectedContentLength.</p> <p>I am completely baffled by this behaviour, I'm hoping that I'm making an obvious n00b mistake and that someone here spots it.</p> <p>The main reason WHY I made the ReportDownloader class was to avoid problems like this one.</p> <p>Thanks in advance to whoever takes the time to scan my code!</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload