2013-04-30 17 views
6

Mam NSURLConnection w podklasie komórek tableview, która może pobrać większość plików. Zauważyłem jednak, że niektóre nie mogą rozpocząć pobierania i przekroczą limit czasu. Przykładem może być adres URL z this, który jest po prostu plikiem zip, który ładnie ładuje się w dowolnej innej przeglądarce. Oto mój kod do pobrania:iOS NSURLConnection nie pobiera plików z określonych adresów URL

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

Ktoś widzi coś, co może to spowodować?

Herezje błąd:

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

Zastosuj metodę protokołu 'connection: didFailWithError:' i zobacz, co otrzymujesz jako błąd. – Malloc

+0

@Malloc mój zły, zapomniałem to opublikować. Mówi tylko, że połączenie minęło. –

+0

Ok, więc jaki jest stos błędów, który masz? – Malloc

Odpowiedz

3

"Mam NSURLConnection w podklasie komórek tableview" - nigdy tego nie rób. Jak Sung-Pil Lim już wskazał poprawnie, TableView Cells zostaną ponownie wykorzystane, co może spowodować ten problem.

W każdym razie dane odpowiedzi połączenia są własnością modelu. Model może zawierać informacje o tym, jak dociera do tych danych. Jeśli dane te nie będą dostępne natychmiast po uzyskaniu dostępu, należy zamiast tego podać wartość zastępczą i uruchomić asynchroniczne zadanie, które pobiera te dane.

Załóżmy, że kontroler widoku ma dostęp do właściwości modelu, obrazu, aby był wyświetlany przez widok. Model nie załadował jeszcze swojego rzeczywistego obrazu - i dlatego zwraca "obraz zastępczy", aby widok mógł coś wyświetlić. Ale w tym samym czasie model uruchamia asynchroniczne zadanie, aby załadować obraz. Kiedy to połączenie zostanie zakończone ładowaniem danych, model aktualizuje wewnętrznie swoją właściwość - zastępując w ten sposób symbol zastępczy rzeczywistym obrazem. Aktualizację właściwości należy wykonać w głównym wątku - ponieważ widoki UIKit mogą również uzyskać dostęp do tej samej właściwości.

Podczas inicjalizacji kontroler widoku zarejestrował się jako obserwator właściwości modelu (patrz KVO). Gdy właściwość modelu zostanie zaktualizowana, kontroler otrzyma powiadomienie. Kontroler widoku następnie wykonuje odpowiednie akcje, aby widok został przerysowany i wyświetla nową zaktualizowaną wartość.

Twój model powinien mieć metodę "anuluj", która zostanie wysłana do modelu ze sterownika, gdy rzeczywista wartość właściwości modelu nie jest już wymagana. Na przykład użytkownik przełączył się na inny widok (zobacz viewWillDisappear).

-1

podwójnie sprawdzić adres URL jest zgodny z RFC 2396. więc musi zawierać http: //

+0

podane przez niego adresy URL: –

2

Próbowałem kody.

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

... To działa na ViewController

'Błąd limitu czasu żądania' doprowadzono do połączenia sieciowego. lub ...

Czy rezygnujesz z UITableViewCell? Jeśli zainicjujesz kody ponownego użycia komórki, zajmij się połączeniem. może przynieść kłopoty. Po prostu myślałem.

Jeśli dołączysz więcej kodów. Czy mógłbym ci pomóc bardziej niż to.

0

Zaczynam od czystej tablicy i po prostu używam podstawowego kodu do pracy do pobrania. Załaduj wiele NSLog (y), aby śledzić wszystko. Jeśli to działa, dodawaj niestandardowy kod i sprawdź, czy natknąłeś się na błąd. Sugeruję podstawowy kod 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"); 
} 
0

spróbuj z HCDownloadViewController i możesz sprawdzić, który URL nie jest pobrany. i następnym razem zsynchronizować ten adres URL, który nie został pobrany.

.h plików

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

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

.m plik

#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

Czy masz jakieś biblioteki (TestFlight, UA itp.) W projekcie? Spróbuj je usunąć i ponownie przetestować. Mieliśmy aplikację, która używała NSUrlConnection z pakietem SDK TestFlight, który powodował różnego rodzaju sporadyczne problemy z siecią.

NSURLConnection timing out

ASIHTTPRequest request times out

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

+0

Pierwszy odsyłacz "Czas wygaśnięcia NSURLConnection" odnosi się do kodu, który i tak jest mało prawdopodobny, aby działał poprawnie - i dlatego nie jest dobrym wskaźnikiem prawdziwego problemu. – CouchDeveloper

0

ponosi żadnej odpowiedzi z zakresu kod odpowiedzi http 200-299 i wyłącza buforowanie na http-złącza.

Powiązane problemy