90

I am using iOS 7's new NSURLSessionDataTask to retrieve data as follows:

NSURLSession *session = [NSURLSession sharedSession];

NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:
request completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
//
}];

How can I increase the time out values to avoid the error "The request timed out" (in NSURLErrorDomain Code=-1001)?

I have checked the documentation for NSURLSessionConfiguration but did not find a way to set the time out value.

Thank you for your help!

mfaani
  • 33,269
  • 19
  • 164
  • 293
AlexR
  • 5,514
  • 9
  • 75
  • 130
  • 1
    Are you doing many requests? If so, just bumping up the timeout is probably not the right approach, but rather you want to constrain the number of concurrent requests that you attempt (e.g. with `NSOperationQueue` with `maxConcurrentOperationCount`). This is not too complicated if you're using the non-delegate based rendition of `NSURLSession` and are using the completion block renditions. Because of significant annoyances with the `NSURLSession` architecture, it's a bit of a pain to do this right if using the delegate-based approach. – Rob May 02 '14 at 15:23
  • 2
    My main problem is that the HTTP server (which is outside of my control) is sometimes under heavy load and responds extremely slow. Do you happen to know the default values for the timeouts for `sharedSession`? – AlexR May 02 '14 at 15:27
  • No, but as the others said, you should just create your own `defaultSessionConfiguration` and set the `timeOutIntervalForRequest` appropriate for your server. It's just that the timeout problems resulting from issuing more than four or five concurrent requests is a completely different problem and suggests a different solution. But if you're only issuing one or two requests and they're still timing out, then setting the `timeoutInterval` properties is the right approach. – Rob May 02 '14 at 15:34

7 Answers7

155

ObjC

NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = 30.0;
sessionConfig.timeoutIntervalForResource = 60.0;

Swift

let sessionConfig = URLSessionConfiguration.default
sessionConfig.timeoutIntervalForRequest = 30.0
sessionConfig.timeoutIntervalForResource = 60.0
let session = URLSession(configuration: sessionConfig)

What docs say

timeoutIntervalForRequest and timeoutIntervalForResource specify the timeout interval for the request as well as the resource.

timeoutIntervalForRequest - The timeout interval to use when waiting for additional data. The timer associated with this value is reset whenever new data arrives. When the request timer reaches the specified interval without receiving any new data, it triggers a timeout.

timeoutIntervalForResource - The maximum amount of time that a resource request should be allowed to take. This value controls how long to wait for an entire resource to transfer before giving up. The resource timer starts when the request is initiated and counts until either the request completes or this timeout interval is reached, whichever comes first.

Based on NSURLSessionConfiguration Class Reference

Rafał Sroka
  • 39,540
  • 23
  • 113
  • 143
  • 7
    Hi reecon, 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 Dec 17 '14 at 05:04
  • I think that through apple's doc the change of `[NSURLSessionConfiguration defaultSessionConfiguration]` will not take effect on `[NSURLSession sharedSession]`? – xi.lin Jan 12 '16 at 13:35
  • 9
    Note the default for `timeoutIntervalForRequest` is 60 seconds and the default for `timeoutIntervalForResource` is 7 days. – Adam Johns Apr 01 '16 at 01:07
  • 6
    timeoutIntervalForRequest works when set to a value lower than 60, but when I set it to a higher value, timeout happens after 60 seconds... – Diogo Souza Dec 15 '17 at 07:06
  • @XiOS did you find any solution to your solution. I am also getting request timed out error within 45 seconds when actually its 60 seconds. – Shirish Feb 04 '19 at 10:46
  • @DiogoSouza I'm also facing the similar issue, if timeout is < 60 it's working otherwise it won't, did you find any solution? – Saif Sep 27 '19 at 15:59
  • @Saif my answer here might be related: https://stackoverflow.com/a/46828688/5097111 – Diogo Souza Sep 27 '19 at 21:38
  • I set it to < 60 but it still takes that long to time out –  Aug 11 '20 at 16:21
  • For anyone still having trouble with the request timing-out after 60 seconds: it turns out there's also a `timeoutInterval` on `URLRequest` itself, which also defaults to 60 seconds. Once you set that value to whatever you want, you also MUST make sure that `configuration.timeoutIntervalForRequest` is set to an equal or greater value; otherwise the `urlRequest.timeoutInterval` value won't work. – musical_coder Feb 02 '22 at 00:34
19

In case Swift developer coming here

to do this, you need to use

    let urlconfig = NSURLSessionConfiguration.defaultSessionConfiguration()
    urlconfig.timeoutIntervalForRequest = 12
    urlconfig.timeoutIntervalForResource = 12
    self.session = NSURLSession(configuration: urlconfig, delegate: self.delegates, delegateQueue: nil)
Sruit A.Suk
  • 7,073
  • 7
  • 61
  • 71
11

In swift 3. timeout 15 seconds.

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = TimeInterval(15)
    configuration.timeoutIntervalForResource = TimeInterval(15)
    let session = URLSession(configuration: configuration)
Danil Shaykhutdinov
  • 2,027
  • 21
  • 26
  • 1
    this does not explain the difference between `timeoutIntervalForRequest` and `timeoutIntervalForResource `. – Martin Oct 24 '17 at 15:17
11

In my case I was increasing the timeout of the wrong class. My timeout error was solved by increasing the timeout of the URLRequest not the URLSession

var request = URLRequest(url: url)
request.timeoutInterval = 30
Nico Dioso
  • 195
  • 2
  • 15
  • 2
    This is what solved the timeout issue for me. I expect that this is required in conjunction with the above settings. – arcady bob Aug 09 '20 at 23:30
4

NSURLSessionConfiguration includes the property timeoutIntervalForRequest:

@property NSTimeInterval timeoutIntervalForRequest

to control the timeout interval. There is also timeoutIntervalForResource for the timeout after the request is initiated.

Wojtek Surowka
  • 20,535
  • 4
  • 44
  • 51
3

In SWIFT 3.0, You need to use

 if let cleanURLString = urlString.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed),
    let theURL: Foundation.URL = Foundation.URL(string: cleanURLString) {

    var task:URLSessionDataTask?
    let urlconfig = URLSessionConfiguration.default
    urlconfig.timeoutIntervalForRequest = 20
    urlconfig.timeoutIntervalForResource = 60
    let session = Foundation.URLSession(configuration: urlconfig, delegate: self, delegateQueue: OperationQueue.main)

    let request = URLRequest(url: theURL)
    request.httpMethod = "POST"
    request.cachePolicy = URLRequest.CachePolicy.reloadIgnoringCacheData
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
    let paramString = YourParameterString
    request.httpBody = paramString.data(using: String.Encoding.utf8)

    task = session.dataTask(with: request) {
        (data, response, error) in
        // Do here
    })
    dataTask.resume()
}
Vitalii
  • 4,267
  • 1
  • 40
  • 45
Lineesh K Mohan
  • 1,702
  • 14
  • 18
  • Note that it is also possible to change timeout after the session was already created: let session = Foundation.URLSession(configuration: ... ); session.configuration.timeoutIntervalForRequest = 20. However this seems to be not working this way for .background sessions. – Vitalii Jan 12 '17 at 16:54
3

For Swift 4:

let config = URLSessionConfiguration.default
config.timeoutIntervalForRequest = TimeInterval(15)
config.timeoutIntervalForResource = TimeInterval(15)
let urlSession = URLSession(configuration: config)

The timeoutIntervalForRequest is for all tasks within sessions based on this configuration. The timeoutIntervalForResource is for all tasks within sessions based on this configuration.