2013-04-30 10 views
6

Ich habe eine NSURLConnection in einer Tabellenansicht Zelle Unterklasse, die die meisten Dateien herunterladen können. Ich habe jedoch festgestellt, dass einige nicht mit dem Herunterladen beginnen und eine Auszeit haben. Ein Beispiel wäre this URL, die nur eine Test-Zip-Datei ist, die in jedem anderen Browser gut heruntergeladen werden kann. Heres mein Code für den DownloadiOS NSURLConnection lädt keine Dateien von bestimmten URLs

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

jemand etwas sehen, die dies verursachen könnte?

Heres der Fehler:

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

Implementieren Sie die 'connection: didFailWithError:' Protokollmethode und sehen Sie, was Sie als Fehler erhalten. – Malloc

+0

@Malloc mein Schlechter habe ich vergessen, das zu posten. Es besagt nur, dass die Verbindung abgelaufen ist. –

+0

Ok, also was ist der Fehler-Stack, den du hast? – Malloc

Antwort

3

"Ich habe eine NSURLConnection in einer Tableview Zelle Unterklasse" - dies nie tun. Wie Sung-Pil Lim bereits richtig angemerkt hat, werden TableView-Zellen wiederverwendet, was dieses Problem verursachen kann.

Wie auch immer, die Antwortdaten Ihrer Verbindung sind eine Eigenschaft des Modells. Das Modell kapselt möglicherweise ein, wie es zu diesen Daten gelangt. Wenn diese Daten nicht sofort verfügbar sind, sobald auf sie zugegriffen wird, sollten sie stattdessen einen "Platzhalter" -Wert bereitstellen und eine asynchrone Task starten, die diese Daten abruft.

Angenommen, auf eine Modelleigenschaft, ein Bild, wird vom View-Controller zugegriffen, um von einer Ansicht angezeigt zu werden. Das Modell hat sein aktuelles Bild noch nicht geladen - und gibt daher ein "Platzhalterbild" zurück, damit die Ansicht etwas anzeigen kann. Gleichzeitig startet das Modell eine asynchrone Aufgabe, um das Bild zu laden. Wenn diese Verbindung mit dem Laden der Daten beendet ist, aktualisiert das Modell intern seine Eigenschaft und ersetzt dadurch den Platzhalter durch das reale Bild. Die Aktualisierung der Eigenschaft sollte im Hauptthread durchgeführt werden, da die UIKit-Ansichten möglicherweise auch auf die gleiche Eigenschaft zugreifen.

Während der Initialisierung hat sich der View Controller als Beobachter der Modelleigenschaft registriert (siehe KVO). Wenn die Eigenschaft des Modells aktualisiert wird, wird der Controller benachrichtigt. Der View Controller führt dann die entsprechenden Aktionen aus, damit die Ansicht neu gezeichnet wird und der neue aktualisierte Wert angezeigt wird.

Ihr Modell sollte eine "Abbrechen" -Methode haben, die vom Controller an das Modell gesendet wird, wenn der tatsächliche Wert der Eigenschaft des Modells nicht mehr benötigt wird. Zum Beispiel wechselte der Benutzer zu einer anderen Ansicht (siehe viewWillDisappear).

-1

überprüfen Sie Ihre URL-Adresse RFC entspricht 2396. so muss es HTTP umfassen: //

+0

die URLs, die er postete –

2

ich Ihre Codes versucht.

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

Es funktioniert ... auf Viewcontroller

Antrag Timeout-Fehler "gebracht wurde Verbindung zu vernetzen. oder ...

Erneut UITableViewCell? Wenn Sie für die Wiederbenutzungscodes initialisieren, gehen Sie mit der Verbindung um. vielleicht in Schwierigkeiten bringen. Ich dachte nur.

Wenn Sie mehr Ihre Codes anhängen. Könnte ich dir mehr helfen?

0

Ich würde mit einem sauberen Schiefer beginnen und nur grundlegenden Code verwenden, um den Download zu arbeiten. Laden Sie in viele NSLog (s), um alles zu verfolgen. Wenn das funktioniert, fügen Sie Ihren benutzerdefinierten Code hinzu und sehen Sie, ob Sie auf einen Fehler stoßen. Ich schlage vor, grundlegenden NSURLConnection Code:

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

versuchen Sie mit HCDownloadViewController und Sie können überprüfen, welche URL nicht heruntergeladen wird. und die nächste Synchronisierung für diese bestimmte URL, die nicht heruntergeladen wurde.

.h-Datei

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

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

.m-Datei

#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

-1

Haben Sie Bibliotheken (Testflug, UA, usw.) im Projekt? Versuchen Sie, sie zu entfernen und erneut zu testen. Wir hatten eine App, die NSUrlConnection mit TestFlight SDK verwendete, die alle möglichen sporadischen Netzwerkprobleme verursachte.

NSURLConnection timing out

ASIHTTPRequest request times out

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

+0

Der erste Link "NSURLConnection Timing Out" bezieht sich auf Code, der wahrscheinlich sowieso nicht richtig funktioniert - und ist daher kein guter Hinweis auf das eigentliche Problem. – CouchDeveloper

0

akzeptieren jede Reaktion mit HTTP-Antwort-Codebereich 200-299 und deaktivieren Caching auf dem HTTP-Anschluss.