Интервал тайм-аута NSMutableURLRequest не принимается во внимание для запросов POST

У меня есть следующая проблема. На NSMutableURLRequest с использованием метода HTTP POST интервал времени ожидания, установленный для соединения, игнорируется. Если у интернет-соединения возникла проблема (неправильный прокси-сервер, плохие DNS-запросы), запрос URL-запроса завершится с ошибкой примерно через 2-4 минуты, но не с NSLocalizedDescription = "timed out";

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

Если используется HTTP метод GET, он работает нормально.  Соединение async над 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];

'

Ответ 1

Согласно сообщению на форуме разработчиков Apple, минимальный интервал ожидания для POST составляет 240 секунд. Любой интервал времени ожидания, меньший, чем этот, игнорируется.

Если вам требуется более короткий интервал времени ожидания, используйте асинхронный запрос вместе с таймером и отмену вызова в NSURLConnection по мере необходимости.

ссылка на тему: здесь

Ответ 2

iOS 6 исправил эту проблему.

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

Исправлено предложение Clay Chambers: с пользовательским таймером Добавлен таймер в подклассе 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];

}

В режиме пользовательской отмены соединение отменяется

[super cancel];     

Ответ 4

Похоже, что описанная здесь проблема по-прежнему сталкивается с iOS 7.1 (или снова появляется). К счастью, это выглядит как установка timeoutIntervalForResource свойство конфигурации NSURLSession может исправить это.

ИЗМЕНИТЬ

Согласно наблюдениям @XiOS, это работает для тайм-аутов короче, чем (около) 2 минут.

Ответ 5

Если вы имеете в виду, как обрабатывать ошибку тайм-аута, я думаю, что никто не ответил на этот вопрос еще

Позвольте мне написать pice моего кода, чтобы Объяснить, что точка

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

Я надеюсь, что эта помощь поможет любому пользователю спросить, как справиться с ошибкой тайм-аута