iOS NSURLConnection 不从某些 URL 下载文件 [英] iOS NSURLConnection not downloading files from certain URLs

查看:52
本文介绍了iOS NSURLConnection 不从某些 URL 下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在可以下载大多数文件的 tableview 单元子类中有一个 NSURLConnection.但是,我注意到有些无法开始下载并超时.一个例子是 this URL,它只是一个测试 zip 文件,可以在任何其他浏览器中正常下载.这是我的下载代码

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?

错误如下:

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."}

推荐答案

我在 tableview 单元格子类中有一个 NSURLConnection" - 永远不要这样做.正如 Sung-Pil Lim 已经正确指出的那样,TableView Cells 将被重用,这可能会导致这个问题.

"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.

假设一个模型的属性,一个图像,将被视图控制器访问,以便被视图显示.模型还没有加载它的实际图像——因此它返回一个占位符图像"以便让视图显示一些东西.但与此同时,模型正在启动一个异步任务来加载图像.当此连接完成数据加载时,模型在内部更新其属性 - 从而用真实图像替换占位符.属性的更新应该在主线程上执行 - 因为 UIKit 视图也可以访问相同的属性.

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.

在初始化期间,视图控制器已注册为模型属性的观察者(参见 KVO).当模型的属性更新时,控制器会收到通知.然后视图控制器执行适当的操作,以便重新绘制视图并显示新的更新值.

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.

您的模型应该有一个取消"方法,当不再需要模型属性的实际值时,该方法将从控制器发送到模型.例如,用户切换到另一个视图(参见 viewWillDisappear).

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).

这篇关于iOS NSURLConnection 不从某些 URL 下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆