2009-09-23 5 views
30

Mam następujący problem. Na wartości NSMutableURLRequest przy użyciu metody HTTP metoda ustawiona dla połączenia jest ignorowana. Jeśli internet ma problem (zły, złe proxy DNS) URL żądania nie powiedzie się po około 2-4 minut, ale nie z NSLocalizedDescription = "timed out";Limit czasu NSMutableURLRequest nie jest brany pod uwagę przy żądaniach POST

NSUnderlyingError = Error Domain=kCFErrorDomainCFNetwork Code=-1001 UserInfo=0x139580 "The request timed out. 

Jeśli metoda http stosowany jest GET to działa dobrze. Połączenie to async przez https.

NSURL *url = [NSURL URLWithString:urlString]; 
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];  

    [request setTimeoutInterval:10]; 

    //Set the request method to post 
    [request setHTTPMethod:@"POST"]; 

    if (body != nil) { 
     [request setHTTPBody:body]; 
    } 

    // Add general parameters to the request 
    if (authorization){ 
     [request addValue: authorization forHTTPHeaderField:@"Authorization"]; 
    } 
    [request addValue: WS_HOST forHTTPHeaderField:@"Host"]; 
    [request addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"]; 

    [[NSURLCache sharedURLCache] setDiskCapacity:0]; 

    [self addToQueueRequest:request withDelegate:delegate]; 

' 
+0

Spróbuj utworzyć obiekt NSMutableURLRequest za pomocą requestWithURL: cachePolicy: timeoutInterval: class method? – catsby

Odpowiedz

28

Zgodnie z postem na forum programistów Apple, minimalny limit czasu dla POST to 240 sekund. Każdy przedział czasu krótszy niż ten jest ignorowany.

Jeśli potrzebujesz krótszego odstępu czasu, użyj żądania asynchronicznego wraz z licznikiem czasu i anuluj wywołanie połączenia NSURLConnection w razie potrzeby.

Link do wątku: here

+1

Czy ktoś może sprawdzić, czy jest to również prawdą w przypadku właściwości timeout podczas wykonywania testu POST w ramach ASIHTTPRequest? – Yannick

+0

jest to pomocne. Z domyślnym limitem czasu otrzymałem błąd podczas połączenia z serwisem (w przypadku bardzo złej sieci) i ustawiłem limit czasu przekraczający 240 i to zadziałało. Dzięki. – lee

10

Usunięto z sugestią Clay Chambersa: z niestandardowego czasomierza dodał stoper w podklasie NSURLConnection

if (needsSeparateTimeout){ 

    SEL sel = @selector(customCancel); 

    NSMethodSignature* sig = [self methodSignatureForSelector:sel]; 

    NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:sig]; 

    [invocation setTarget:self]; 

    [invocation setSelector:sel]; 

    NSTimer *timer = [NSTimer timerWithTimeInterval:WS_REQUEST_TIMEOUT_INTERVAL invocation:invocation repeats:NO]; 

    [[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode]; 

} 

W zwyczaju anulować metoda połączenie zostanie przerwane

[super cancel];  
26

System iOS 6 rozwiązał ten problem.

NSMutableURLRequest *request = [NSMutableURLRequest 
           requestWithURL:[NSURL URLWithString:url] 
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20]; 

[request setHTTPMethod:method]; 
[request setHTTPBody:requestBody]; 
NSLog(@"%f", [request timeoutInterval]); 
//20.0 in iOS 6 
//240.0 in iOS 4.3, 5.0, 5.1 
3

Wygląda na to, że opisywany problem nadal występuje w systemie iOS 7.1 (lub został ponownie wyświetlony). Na szczęście wygląda na to, że ustawienie wartości timeoutIntervalForResource w konfiguracji na NSURLSession może to naprawić.

EDIT

Według @XiOS obserwacji to działa na limity czasu krótszych niż (około 2 minuty).

+0

Każdy pomysł na to, czy ma jakieś poprawki tego w ios8, czy nadal występuje w ios8? – XiOS

+0

Naprawiono to w moim poście :) –

+0

Cześć Julian Królu, To wygląda dobrze, ale jeszcze tego nie opracowałem.Moim rzeczywistym problemem jest ustawienie limitu czasu na 180 sekund dla mojego NSMutableURLRequest, delegat didFailWithError: zostanie wyzwolony w przedziale od 75 do 220 sekund i kilka razy większym od tego, ale nie dokładnie w przedziale 180 sekund. Wykonuję asynchroniczne wywołania usługi WWW za pomocą metody POST. Czy masz na myśli, że określony przedział czasu będzie działał dokładnie z NSURLSession? – XiOS

0

Jeśli masz na myśli, jak radzić błąd przekroczenia limitu czasu, myślę, że nikt nie odpowie na to pytanie jeszcze

Zapiszę pice mojego kodu, aby wyjaśnić, że punkt

// replace "arg" with your argument you want send to your site 
NSString * param = [NSString stringWithFormat:@"arg"]; 

    NSData *Postdata = [param dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; 
    NSString *postLength = [NSString stringWithFormat:@"%lu",(unsigned long)[Postdata length]]; 
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init]; 
// replace "yoursite" with url of site you want post to 
    [request setURL:[NSURL URLWithString:[NSString stringWithFormat:@"http//yoursite"]]]; 
// set what ever time you want in seconds 120 mean 2 min , 240 mean 4 min 
    [request setTimeoutInterval:120]; 
    [request setHTTPMethod:@"POST"]; 
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"]; 
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Current-Type"]; 

    [request setHTTPBody:Postdata]; 
    NSURLConnection * connection = [[NSURLConnection alloc]initWithRequest:request delegate:self]; 

// if request time out without response from server error will occurred 

-(void) connection:(NSURLConnection *) connection didFailWithError:(NSError *)error {  
    if (error.code == NSURLErrorTimedOut) 
     // handle error as you want 
     NSLog(@"Request time out , Please try again later"); 
} 

Mam nadzieję, że to pomoże z jednego zapytaj, jak rozwiązać problem przekroczenia limitu czasu: