NSURLSession:如何增加URL请求的超时时间?


74

我正在使用iOS 7的新版NSURLSessionDataTask本来检索数据,如下所示:

NSURLSession *session = [NSURLSession sharedSession];

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

如何增加超时值以避免错误"The request timed out"(在 NSURLErrorDomainCode =中-1001)?

我已经检查了NSURLSessionConfiguration的文档,但没有找到设置超时值的方法。

感谢您的帮助!


1
您是否正在处理很多请求?如果是这样,增加超时时间可能不是正确的方法,而是您想限制尝试的并发请求的数量(例如NSOperationQueuemaxConcurrentOperationCount)。如果您使用的非基于委托的再现形式,NSURLSession并且正在使用完成块的再现形式,那么这并不太复杂。由于该NSURLSession体系结构有很多烦人之处,因此如果使用基于委托的方法来正确执行此操作会有些痛苦。
罗布

2
我的主要问题是HTTP服务器(这是我无法控制的)有时负载很重,响应速度非常慢。您是否知道超时的默认值sharedSession
AlexR 2014年

不,但是正如其他人所说,您应该创建自己的服务器defaultSessionConfigurationtimeOutIntervalForRequest为服务器设置合适的服务器。仅仅由于发出四个或五个以上的并发请求而导致的超时问题是完全不同的问题,并提出了不同的解决方案。但是,如果您仅发出一个或两个请求,而它们仍在超时,则设置timeoutInterval属性是正确的方法。
罗布

Answers:


127

对象

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

迅速

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

文档怎么说

timeoutIntervalForRequesttimeoutIntervalForResource指定请求和资源的超时间隔。

timeoutIntervalForRequest-等待其他数据时使用的超时间隔。每当有新数据到达时,与该值关联的计时器就会重置。当请求计时器达到指定的间隔但未接收到任何新数据时,它将触发超时。

timeoutIntervalForResource-资源请求应允许的最长时间。该值控制放弃之前等待整个资源传输的时间。资源计时器在启动请求时启动,并计数直到请求完成或达到超时间隔(以先到者为准)。

基于NSURLSessionConfiguration类的参考


7
reecon,您好,我希望Web服务的超时间隔为180秒(3分钟)。自从我了解了NSURLSESSION及其timeoutIntervalForRequest和timeoutIntervalForResource以来,我尝试使用它们,它们再次产生与NSMutableURLRequest.ie的timeOutInterval相同的结果,我将超时间隔设置为180秒,例如,sessionConfig.timeoutIntervalForRequest = 180.0; sessionConfig.timeoutIntervalForResource = 180.0; 但我在75秒内或以某个随机时间间隔收到失败回叫,说“请求超时”。有什么想法吗?
XiOS 2014年

我认为通过Apple的文档更改[NSURLSessionConfiguration defaultSessionConfiguration]不会生效[NSURLSession sharedSession]吗?
xi.lin

7
请注意,默认timeoutIntervalForRequest值为60秒,默认timeoutIntervalForResource值为7天。
亚当·约翰斯

5
将timeoutIntervalForRequest设置为小于60的值时有效,但是当我将其设置为较高的值时,则在60秒后发生超时...
Diogo Souza

@XiOS您是否找到解决方案的任何解决方案。我也在45秒内收到请求超时错误,而实际上是60秒。
Shirish

17

万一Swift开发者来了

为此,您需要使用

    let urlconfig = NSURLSessionConfiguration.defaultSessionConfiguration()
    urlconfig.timeoutIntervalForRequest = 12
    urlconfig.timeoutIntervalForResource = 12
    self.session = NSURLSession(configuration: urlconfig, delegate: self.delegates, delegateQueue: nil)

我收到无法识别的选择器,该接收器发送给timeoutIntervalForRequest实例错误
Marcus

我已经为Swift 3更新了,但是我得到了错误类没有成员委托?
adamprocter

@ sruit-a-suk并非“不变”且“可变”可变。因此,超时请求和资源永远不会被设置吗?
马修·弗格森

9

快速3.超时15秒。

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

这并不能解释之间的差异timeoutIntervalForRequesttimeoutIntervalForResource
马丁

4

NSURLSessionConfiguration包含属性timeoutIntervalForRequest:

@property NSTimeInterval timeoutIntervalForRequest

控制超时间隔。启动请求后,还有超时timeoutIntervalForResource。


3

就我而言,我正在增加错误的课的超时时间。我的超时错误是通过增加URLRequest而不是URLSession的超时来解决的

var request = URLRequest(url: url)
request.timeoutInterval = 30

这就是为我解决超时问题的原因。我希望这与上述设置结合在一起是必需的。
arcady鲍勃,

2

在SWIFT 3.0中,您需要使用

 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()
}

请注意,也可以在创建会话后更改超时:let session = Foundation.URLSession(configuration:...); session.configuration.timeoutIntervalForRequest =20。但是,这对于.background会话似乎不起作用。
Vitalii

1

对于Swift 4:

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

timeoutIntervalForRequest适用于基于此配置的会话中的所有任务。timeoutIntervalForResource适用于基于此配置的会话中的所有任务。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.