iOS NSURLConnection no descarga files de ciertas URL

Tengo una NSURLConnection en una subclass de celda tableview que puede download la mayoría de los files. Noté, sin embargo, que algunos no pueden iniciar la descarga y el time de espera. Un ejemplo sería esta URL, que es solo un file comprimido de testing que se descarga bien en cualquier otro browser. Aquí está mi código para la descarga

 -(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 = UTTypeCreatePrefernetworkingIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL); CFStringRef extension = UTTypeCopyPrefernetworkingTagWithClass(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); } 

¿Alguien ve algo que pueda causar esto?

Aquí está el 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."} 

"Tengo una NSURLConnection en una subclass de celda tableview": nunca hagas esto. Como Sung-Pil Lim ya señaló correctamente, las células de TableView se reutilizarán, lo que puede causar este problema.

De todos modos, los datos de respuesta de su connection son propiedad del model. El model podría encapsular cómo llega a estos datos. Si esos datos no están disponibles inmediatamente una vez que se accederá, debe proporcionar un valor de "marcador de position" y comenzar una tarea asíncrona que recupera estos datos.

Supongamos que la propiedad de un model, una image, será accedida por el controller de vista para que se visualice mediante una vista. El model aún no ha cargado su image real, y por lo tanto devuelve una "image de marcador de position" para permitir que la vista muestre algo. Pero al mismo time, el model está comenzando una tarea asíncrona para cargar la image. Cuando esta connection termina de cargarse con los datos, el model actualiza internamente su propiedad, reemplazando así el marcador de position con la image real. La actualización de la propiedad debe realizarse en el hilo principal, ya que las vistas de UIKit también pueden acceder a la misma propiedad.

Durante la initialization, el controller de vista se ha registrado como un observador de la propiedad del model (ver KVO). Cuando se actualiza la propiedad del model, el controller recibe una notificación. El controller de vista realiza las acciones apropiadas para que la vista se vuelva a dibujar y muestre el nuevo valor actualizado.

Su model debe tener un método de "cancelación", que se enviará al model desde el controller cuando ya no se necesite el valor real de la propiedad del model. Por ejemplo, el usuario cambió a otra vista (ver viewWillDisappear).

Probé tus códigos.

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

Está funcionando … en ViewController

'request de error de time de espera' se llevó a la connection de networking. o…

¿Está volviendo a UITableViewCell? Si inicializa los códigos de reutilización de celdas, se ocupa de la connection. tal vez traer problemas. Solo pensé

Si adjuntas más códigos. ¿Podría ayudarlo más que esto?

Comencé con una pizarra limpia y simplemente usé un código básico para trabajar la descarga. Cargue muchos NSLog (s) para rastrear todo. Si eso funciona, sigue agregando tu código personalizado y mira si tropieza con un error. Sugiero el código básico de 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"); } 

intente con HCDownloadViewController y puede verificar qué url no se descarga. y la próxima vez que se sincronice para esa url en particular que no se haya descargado.

file .h

 #import "HCDownloadViewController.h" @interface HomeViewController_iPhone : UIViewController<HCDownloadViewControllerDelegate> { HCDownloadViewController *tblDownloadHairStyle; } @property (nonatomic,retain) HCDownloadViewController *tblDownloadHairStyle; 

file .m

 #define kAppDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) 

@sintetizar 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

acepte cualquier respuesta con el range de código de respuesta http 200-299 y deshabilite el almacenamiento en caching en el conector http.

comtesting dos veces tu dirección URL conforme a RFC 2396. por lo que debe include HTTP: //

¿Tiene alguna biblioteca (TestFlight, UA, etc.) en el proyecto? Intente eliminarlos y volver a probarlos. Teníamos una aplicación que usaba NSUrlConnection con TestFlight SDK que causaba todo tipo de problemas de networking esporádicos.

NSURLConnection timing out

ASIHTTPloop de request más corto

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