32

I have the following problem. On a NSMutableURLRequest using the HTTP method POST the timeout interval set for the connection is ignored. If the internet connection has a problem (wrong proxy, bad dns) the url request fails after about 2-4 minutes but not with NSLocalizedDescription = "timed out";

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

If the http method used is GET it works fine. The connection is async over 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];

'
Julian
  • 9,299
  • 5
  • 48
  • 65
user177844
  • 421
  • 1
  • 5
  • 6
  • Try creating the NSMutableURLRequest object with requestWithURL:cachePolicy:timeoutInterval: class method? – catsby Sep 25 '09 at 21:05

5 Answers5

28

iOS 6 has fixed this issue.

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
freestyler
  • 5,224
  • 2
  • 32
  • 39
28

According to a post on the Apple developer forum, the minimum timeout interval for POST is 240 seconds. Any timeout interval shorter than that is ignored.

If you require a shorter timeout interval, use an async request along with a timer and call cancel on the NSURLConnection as needed.

link to thread: here

  • 1
    Can someone verify that this is also true for the timeout property when doing a POST with the ASIHTTPRequest framework? – Yannick Apr 23 '12 at 13:07
  • it's helpful.with default time out I got the error when call to service(in case very bad network) and I set the timeout greater than 240 and it's worked.Thanks. – lee Jun 05 '15 at 07:59
10

Fixed with Clay Chambers's suggestion: with a custom timer Added a timer in a subclass of 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];

}

In the custom cancel method the connection is cancelled

[super cancel];     
James Zaghini
  • 3,895
  • 4
  • 45
  • 61
user177844
  • 421
  • 1
  • 5
  • 6
3

It looks like problem described here is still facing iOS 7.1 (or reappeared). Fortunately it looks like setting timeoutIntervalForResource property on the configuration on the NSURLSession can fix this.

EDIT

According to @XiOS observations this works for timeouts shorter than (around) 2 minutes.

Julian
  • 9,299
  • 5
  • 48
  • 65
  • Any idea on whether this has any kind of fixes for this in ios8 or still persists in ios8 too? – XiOS Dec 16 '14 at 13:50
  • Fix is described in my post :) – Julian Dec 16 '14 at 13:51
  • Hi Julian Król, That looks good though i havent worked out it yet. My actual issue is when i set a time out interval of 180 seconds for my NSMutableURLRequest, the didFailWithError: delegate gets triggered at the interval ranging from 75 to 220 seconds and some times greater than this , but not exactly at the interval of 180 seconds. I am making asynchronous web service calls with POST method. So do you mean that the specified time out interval will work exactly with NSURLSession? – XiOS Dec 16 '14 at 14:04
  • I think you should try this out, from my experience on NSMutableURLRequest it didn't work at all whereas for NSURLSession worked fine. – Julian Dec 16 '14 at 14:06
  • I tried this out, but the above behaviour i mentioned, remains the same with NSURLSESSION too :( – XiOS Dec 17 '14 at 05:39
  • Sad, in my case it worked. I have removed timeouts from request and moved them to session and worked like a charm. Which iOS version face a problem in your case? – Julian Dec 17 '14 at 08:35
  • i am testing in ios7.1.1 and ios8. What is the interval that you are setting? – XiOS Dec 17 '14 at 11:10
  • I found that, this is not doing good for greater time out intervals but ofcourse behaving well for time out interval of a minute or two. That was really a right direction towards NSURLSESSION after surfing a lot. Thankyou Julian Król! – XiOS Dec 19 '14 at 11:06
  • Thanks for the update I will update my answer according to your observation :-) – Julian Dec 19 '14 at 11:14
0

If you mean how to handle timeout error , I think no one answer this question yet

Let me write pice of my code to Explain that point

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

I hope this help with any one ask how to handle timeout error

Mina Fawzy
  • 20,852
  • 17
  • 133
  • 156