NSURLSessionConfiguration timeoutIntervalForRequest vs NSURLSession timeoutInterval

12,209

Solution 1

As my investigation on iOS 7.0.3, timeoutInterval for NSURLRequest does not get any effects when it is used with NSURLSession.

Whether you set timeoutIntervalForRequest for NSURLSessionConfiguration or not, timeoutInterval is just ignored.

You can use my tiny sample application NetworkTimeoutSample for checking this behavior.

When you set 1 for 'URLReq' field, which affects timeoutInterval for NSURLRequest, then click 'NSURLSession With URLRequest' button, your session will not get timeout error.

You also may recognize you should set timeoutIntervalForResource, instead of timeoutIntervalForRequest for NSURLSession if you'd like to get same timeout effect for timeoutInterval of NSURLRequest.

If you set both timeoutIntervalForRequest and timeoutIntervalForResource value for NSURLSessionConfiguration, smaller value will be affected(I feel this behavior is different from current API document).

There are no documentation about those specifications, so it might be changed on future iOS version.

Solution 2

Since iOS8, the NSUrlSession in background mode does not call this delegate method if the server does not respond. -(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error The download/upload remains idle indefinitely. This delegate is called on iOS7 with an error when the server does not respond.

In general, an NSURLSession background session does not fail a task if something goes wrong on the wire. Rather, it continues looking for a good time to run the request and retries at that time. This continues until the resource timeout expires (that is, the value of the timeoutIntervalForResource property in the NSURLSessionConfiguration object you use to create the session). The current default for that value is one week! In other words, the behaviour of failing for a timeout in iOS7 was incorrect. In the context of a background session, it is more interesting to not fail immediately because of network problems. So since iOS8, NSURLSession task continues even if it encounters timeouts and network loss. It continues however until timeoutIntervalForResource is reached.

So basically timeoutIntervalForRequest won't work in Background session but timeoutIntervalForResource will.

I got this answer from one of the members of Apple Staff at the developer forum. Also, I have verified this by implementing.

Solution 3

NSURLSession offers two timeouts, timeoutIntervalForRequest and timeoutIntervalForResource.

timeoutIntervalForRequest is enforced by a timer that is reset every time data is transferred. So if you set this timeout to 30 seconds and at least one byte of data is transferred every 30 seconds, the timeout is never hit. The timeout is only hit if absolutely no data is transferred for 30 seconds. You could also say that this is the maximum idle time for a session task. The default value is 60 seconds.

timeoutIntervalForResource is enforced by a timer that is never reset. It is started when a session task is started and it is stopped when a session task is stopped or has finished. So this is the maximum total amount of time a session task can take and this is what most people think of, when they hear "timeout". As a session task may also be a download of a 100 GB file over a very slow Internet link, the default value here is 7 days!

NSURLRequest (and its mutable subclass) offers only one property timeoutInterval. This timeout value behaves like timeoutIntervalForRequest as the documentation of NSURLRequest says:

If during a connection attempt the request remains idle for longer than the timeout interval, the request is considered to have timed out.

Source: timeoutInterval - NSURLRequest | Apple Developer Documentation

And the documentation of NSURLSession says:

Note

In some cases, the policies defined in this configuration may be overridden by policies specified by an NSURLRequest object provided for a task. Any policy specified on the request object is respected unless the session’s policy is more restrictive.

Source: NSURLSessionConfiguration - Foundation | Apple Developer Documentation

So the timeoutInterval of a NSURLRequest would override the timeoutIntervalForRequest of a NSURLSession but only if it is considered to be "more restrictive" by the system, otherwise the value of NSURLSession will win.

Solution 4

Looks like things changed since n-miyo tested it.

The apple documentation states the NSURLRequest value will override the session configuration.

In some cases, the policies defined in this configuration may be overridden by policies specified by an NSURLRequest object provided for a task. Any policy specified on the request object is respected unless the session’s policy is more restrictive. For example, if the session configuration specifies that cellular networking should not be allowed, the NSURLRequest object cannot request cellular networking.

Share:
12,209

Related videos on Youtube

Joe Licari
Author by

Joe Licari

Updated on June 04, 2022

Comments

  • Joe Licari
    Joe Licari almost 2 years

    With the new NSURLSession, there is now a timeoutIntervalForRequest on the NSURLSessionConfiguration object used to create the session.

    But there is still a timeoutInterval on the NSURLRequest object that can be used to create the NSURLSessionTask in the session.

    My question is, if the configuration has a timeoutIntervalForRequest set to 30, but the NSURLRequest use to create the task has a timeoutInterval of 60, which timeout interval will actually be used?

  • XiOS
    XiOS over 9 years
    i want the time out interval of my web services to be 180 seconds(3 min).Since i read about NSURLSESSION and its timeoutIntervalForRequest and timeoutIntervalForResource, i tried using these, which again yielded same results as timeOutInterval of NSMutableURLRequest.i.e., i am setting time out interval of 180 seconds like sessionConfig.timeoutIntervalForRequest = 180.0; sessionConfig.timeoutIntervalForResource = 180.0; but i am receiving failure call back in 75 seconds or at some random time interval, saying 'The request timed out'. Have any idea on this?
  • XiOS
    XiOS over 9 years
    Is it actually like we could set time outs only for background processes?
  • Pranjal Bikash Das
    Pranjal Bikash Das over 8 years
    hi @XiOS, do you find the solution of maximum timeout of not more than 75 seconds?
  • GarySabo
    GarySabo about 8 years
    I'm using NSURLSession to check whether a given url is still active or broken, any recommendation on what time I should set timeoutIntervalForResource to? My goal is to set it so that its the absolute minimum time needed to determine if the url is active or not?
  • mutable.me
    mutable.me about 8 years
    In my experiments, if you set timeoutInterval to something like 15 seconds for NSURLRequest and NSURLSession is a background session, iOS will keep retrying approx. every 15 seconds up until timeoutIntervalForResource is reached. It will be happening, of course, if iOS thinks that your network is good. No callback will be called - it's true. Tested on iOS 9.2/
  • Utsav Dusad
    Utsav Dusad about 8 years
    @GarySabo: I think for that you should use reachability module.
  • Mecki
    Mecki about 5 years
    The timer of timeoutIntervalForRequest is reset whenever data arrives, no matter how much data (just a single byte arriving would reset it), it only causes a timeout if absolutely no data arrives for this interval. The timer for timeoutIntervalForResource is never reset, it produces a timeout unless the task fully completed as that will stop that timer from firing.