Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS NSURLConnection not downloading files from certain URLs

I have an NSURLConnection in a tableview cell subclass that can download most files. I noticed, however, that some fail to start downloading, and time out. An example would be this URL, which is just a test zip file that downloads fine in any other browser. Heres my code for the download

-(void)downloadFileAtURL:(NSURL *)url{
    self.downloadedData = [[NSMutableData alloc] init];
    self.url = url;
    conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:self.url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1200.0] delegate:self startImmediately:YES];
}

- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{
    int statusCode = [response statusCode];
    if (statusCode == 200){
        self.fileName.text = response.URL.lastPathComponent;
        self.respo = response;
        expectedLength = [response expectedContentLength];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
    [self.downloadedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    CFStringRef mimeType = (__bridge CFStringRef)[_respo MIMEType];
    CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
    CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
    NSString *fileName = [NSString stringWithFormat:@"%@.%@", [[_respo suggestedFilename] stringByDeletingPathExtension], (__bridge NSString *)extension];
    [[NSFileManager defaultManager] createFileAtPath:[[self docsDir] stringByAppendingPathComponent:[NSString stringWithFormat:@"Downloads/%@", fileName]] contents:_downloadedData attributes:nil];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
    NSLog(@"Download failed with error: %@", error);
}

Anybody see anything that might cause this?

Heres the error:

Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x1fd2c650 
{NSErrorFailingURLStringKey=http://download.thinkbroadband.com/10MB.zip, 
NSErrorFailingURLKey=http://download.thinkbroadband.com/10MB.zip, 
NSLocalizedDescription=The request timed out., NSUnderlyingError=0x1fdc90b0 "The request timed out."}
like image 777
Chris Loonam Avatar asked Apr 30 '13 22:04

Chris Loonam


2 Answers

"I have an NSURLConnection in a tableview cell subclass " - never do this. As Sung-Pil Lim already pointed out correctly, TableView Cells will be reused which may cause this issue.

Anyway, the response data of your connection is a property of the model. The model might encapsulate how it gets to this data. If that data is not immediately available once it will be accessed, it should provide a "placeholder" value instead and start an asynchronous task which retrieves this data.

Suppose a model's property, an image, will be accessed by the view controller in order to be displayed by a view. The model has not yet loaded its actual image - and thus it returns a "placeholder image" in order to let the view display something. But at the same time the model is starting an asynchronous task to load the image. When this connection is finished loading with the data, the model updates internally its property - thereby replacing the placeholder with the real image. The update of the property should be performed on the main thread - since the UIKit views may access the same property as well.

During initialization, the View Controller has registered as an observer of the model's property (see KVO). When the model's property is updated, the controller gets notified. The View Controller then performs appropriate actions so that the view will be redrawn and displays the new updated value.

Your model should have a "cancel" method, which will be send to the model from the controller when the actual value of the model's property is not required anymore. For example, the user switched to another view (see viewWillDisappear).

like image 193
CouchDeveloper Avatar answered Oct 04 '22 19:10

CouchDeveloper


I tried your codes.

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
  [self.downloadedData appendData:data];
  NSLog(@"%d", data.length);
}
2013-05-04 01:51:13.811 SomethingTodo[2732:c07] 1124
2013-05-04 01:51:13.856 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:14.075 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.180 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.295 SomethingTodo[2732:c07] 1448

It's working... on ViewController

'request timeout error' was brought to network connection. or...

Are you resuing UITableViewCell? If you initialize for cell reuse codes deal with connection. maybe bring to trouble. Just i thought.

If you attach more your codes. Could I help you more then this.

like image 42
Sung-Pil Lim Avatar answered Oct 04 '22 17:10

Sung-Pil Lim