iOS NSURLConnection不从某些URL下载文件

时间:2013-04-30 22:28:23

标签: ios objective-c nsurlconnection

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

-(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);
}

有人看到任何可能导致这种情况的事吗?

继承错误:

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

7 个答案:

答案 0 :(得分:3)

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

无论如何,您的连接的响应数据是模型的属性。该模型可能会封装它如何获取此数据。如果该数据一旦被访问就不能立即获得,它应该提供一个“占位符”值,并启动一个异步任务来检索这些数据。

假设视图控制器将访问模型的属性(图像),以便由视图显示。该模型尚未加载其实际图像 - 因此它返回“占位符图像”以便让视图显示某些内容。但与此同时,模型正在启动异步任务来加载图像。当此连接完成加载数据时,模型会在内部更新其属性 - 从而用实际图像替换占位符。应该在主线程上执行属性的更新 - 因为UIKit视图也可以访问相同的属性。

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

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

答案 1 :(得分:2)

我尝试了你的代码。

- (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

它正在ViewController

上工作

'请求超时错误'被带到网络连接。或...

您是否正在重新使用UITableViewCell?如果初始化单元重用代码处理连接。也许会带来麻烦。只是我想。

如果您附加更多代码。我可以帮助你吗?

答案 2 :(得分:0)

我会从一个干净的平板开始,只需使用基本代码来完成下载。加载许多NSLog以跟踪所有内容。如果可行,请继续添加自定义代码,看看是否偶然发现错误。我建议使用基本的NSURLConnection代码:

-(void)startDownloading:(NSString *)URLaddress{
NSLog(@"start downloading from: %@",URLaddress);
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:[URLaddress stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]
                                          cachePolicy:NSURLRequestUseProtocolCachePolicy
                                      timeoutInterval:60.0];
__unused NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"didReceiveResponse: %@", response);
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(@"didReceiveData");
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"Connection failed! Error - %@ %@",[error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"connectionDidFinishLoading");
}

答案 3 :(得分:0)

尝试使用HCDownloadViewController,您可以检查未下载的网址。以及下次未同步的特定网址的同步。

.h文件

#import "HCDownloadViewController.h"
@interface HomeViewController_iPhone : UIViewController<HCDownloadViewControllerDelegate>
{
    HCDownloadViewController *tblDownloadHairStyle;

}
@property (nonatomic,retain) HCDownloadViewController *tblDownloadHairStyle;

.m文件

#define kAppDirectoryPath   NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)

@synthesize tblDownloadHairStyle

- (void)viewDidLoad
{
    [super viewDidLoad];
     tblDownloadHairStyle=[[HCDownloadViewController alloc] init];
    tblDownloadHairStyle.delegate=self;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{

    [self createDocumentDirectory:@"Downloaded_HairStyle"];
    NSString *pathHair=[self getDocumentDirectoryPath:@"Downloaded_HairStyle"];
    tblDownloadHairStyle.downloadDirectory = pathHair;
     ////You can put url in for loop, it create queue for downloading.
    [tblDownloadHairStyle downloadURL:[NSURL URLWithString:@"yourUrl"] userInfo:YourResponseDictonary];
}


-(void)createDocumentDirectory:(NSString*)pStrDirectoryName
{
    NSString *dataPath = [self getDocumentDirectoryPath:pStrDirectoryName];

    if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
        [[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:NULL];
}

-(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
    NSString *strPath = @"";
    if(pStrPathName)
        strPath = [[kAppDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];

    return strPath;
}


#pragma mark-
#pragma mark-HCDownloadViewController Delegate Method
- (void)downloadController:(HCDownloadViewController *)vc startedDownloadingURL:(NSURL *)url userInfo:(NSDictionary *)userInfo {

}

- (void)downloadController:(HCDownloadViewController *)vc finishedDownloadingURL:(NSURL *)url toFile:(NSString *)fileName userInfo:(NSDictionary *)userInfo {

    if (vc==tblDownloadHairStyle) {
       if ([tblDownloadHairStyle numberOfDownloads]==0) {

            NSLog(@"AllDownLoad are complete");
         }
    }
}
- (void)downloadController:(HCDownloadViewController *)vc failedDownloadingURL:(NSURL *)url withError:(NSError *)error userInfo:(NSDictionary *)userInfo {
     NSLog(@"failedDownloadingURL=%@",url);
}

https://github.com/H2CO3/HCDownload

答案 4 :(得分:0)

接受http响应代码范围为200-299的任何响应,并禁用http连接器上的缓存。

答案 5 :(得分:-1)

仔细检查您的网址是否符合RFC 2396.所以它必须包含HTTP://

答案 6 :(得分:-1)

项目中是否有任何库(TestFlight,UA等)?尝试删除它们并重新测试。我们有一个应用程序使用NSUrlConnection和TestFlight SDK,导致各种零星的网络问题。

NSURLConnection timing out

ASIHTTPRequest request times out

https://github.com/AFNetworking/AFNetworking/issues/307