NSURLSession: How to increase time out for URL requests?
Asked Answered
S

7

91

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!

Seclusion answered 2/5, 2014 at 12:59 Comment(3)
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.Facture
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?Seclusion
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.Facture
S
157

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

Synergistic answered 2/5, 2014 at 13:9 Comment(9)
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?Marinamarinade
I think that through apple's doc the change of [NSURLSessionConfiguration defaultSessionConfiguration] will not take effect on [NSURLSession sharedSession]?Ruvolo
Note the default for timeoutIntervalForRequest is 60 seconds and the default for timeoutIntervalForResource is 7 days.Tribble
timeoutIntervalForRequest works when set to a value lower than 60, but when I set it to a higher value, timeout happens after 60 seconds...Palatable
@Marinamarinade did you find any solution to your solution. I am also getting request timed out error within 45 seconds when actually its 60 seconds.Infidelity
@DiogoSouza I'm also facing the similar issue, if timeout is < 60 it's working otherwise it won't, did you find any solution?Docilla
@Docilla my answer here might be related: https://mcmap.net/q/245788/-httpmaximumconnectionsperhost-is-ignored-in-afhttpsessionmanagerPalatable
I set it to < 60 but it still takes that long to time outDiminish
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.Bless
P
20

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)
Precis answered 24/5, 2015 at 19:0 Comment(3)
I'm getting an unrecognized selector sent to instance error for timeoutIntervalForRequestKohinoor
I have updated for Swift 3 but I get the error Class has no member delegates ?Courtund
@sruit-a-suk Isn't "let" immutable and "var" mutable. So the timeout request and resources never get set?Ssw
V
12

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
Volauvent answered 12/2, 2019 at 1:52 Comment(1)
This is what solved the timeout issue for me. I expect that this is required in conjunction with the above settings.Scholasticism
E
11

In swift 3. timeout 15 seconds.

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForRequest = TimeInterval(15)
    configuration.timeoutIntervalForResource = TimeInterval(15)
    let session = URLSession(configuration: configuration)
Emigrant answered 3/2, 2017 at 9:41 Comment(1)
this does not explain the difference between timeoutIntervalForRequest and timeoutIntervalForResource .Wilt
M
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.

Murine answered 2/5, 2014 at 13:3 Comment(0)
E
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()
}
Excite answered 4/11, 2016 at 8:28 Comment(1)
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.Greengrocer
I
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.

Invigorate answered 26/12, 2017 at 12:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.