【问题标题】:NSURLSession: How to increase time out for URL requests?NSURLSession:如何增加 URL 请求的超时时间?
【发布时间】:2014-06-19 04:14:12
【问题描述】:

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

NSURLSession *session = [NSURLSession sharedSession];

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

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

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

感谢您的帮助!

【问题讨论】:

  • 你在做很多请求吗?如果是这样,只是增加超时可能不是正确的方法,而是您想要限制您尝试的并发请求的数量(例如,NSOperationQueuemaxConcurrentOperationCount)。如果您使用NSURLSession 的基于非委托的再现并且使用完成块再现,这并不太复杂。由于NSURLSession 架构存在很大的烦恼,如果使用基于委托的方法,要正确执行此操作会有点痛苦。
  • 我的主要问题是 HTTP 服务器(不在我的控制范围内)有时负载很重,响应速度极慢。您是否知道sharedSession 的超时默认值?
  • 不,但正如其他人所说,您应该只创建自己的defaultSessionConfiguration 并设置适合您服务器的timeOutIntervalForRequest。只是发出超过四五个并发请求导致的超时问题是一个完全不同的问题,并提出了不同的解决方案。但是,如果您只发出一两个请求并且它们仍然超时,那么设置timeoutInterval 属性是正确的方法。

标签: ios objective-c swift http nsurlsession


【解决方案1】:

NSURLSessionConfiguration 包含属性 timeoutIntervalForRequest:

@property NSTimeInterval timeoutIntervalForRequest

控制超时间隔。还有 timeoutIntervalForResource 表示请求发起后的超时时间。

【讨论】:

    【解决方案2】:

    ObjC

    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 Class Reference

    【讨论】:

    • 嗨 reecon,我希望我的 Web 服务的超时间隔为 180 秒(3 分钟)。因为我阅读了 NSURLSESSION 及其 timeoutIntervalForRequest 和 timeoutIntervalForResource,我尝试使用这些,再次产生相同的结果结果为 NSMutableURLRequest.ie 的 timeOutInterval,我设置了 180 秒的超时间隔,如 sessionConfig.timeoutIntervalForRequest = 180.0; sessionConfig.timeoutIntervalForResource = 180.0;,但我在 75 秒或某个随机时间间隔内收到失败回调,说“请求超时”。对此有什么想法吗?
    • 我认为通过苹果的文档更改[NSURLSessionConfiguration defaultSessionConfiguration]不会对[NSURLSession sharedSession]生效?
    • 注意timeoutIntervalForRequest 的默认值为 60 秒,timeoutIntervalForResource 的默认值为 7 天。
    • timeoutIntervalForRequest 在设置为低于 60 的值时有效,但当我将其设置为更高的值时,超时发生在 60 秒后...
    • @XiOS 你有没有找到任何解决方案。我也在 45 秒内收到请求超时错误,而实际上是 60 秒。
    【解决方案3】:

    万一 Swift 开发者来到这里

    要做到这一点,你需要使用

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

    【讨论】:

    • 我收到一个无法识别的选择器发送到实例错误 timeoutIntervalForRequest
    • 我已针对 Swift 3 进行了更新,但出现错误 Class has no member delegates ?
    • @sruit-a-suk 不是“让”不可变和“变”可变。所以超时请求和资源永远不会设置?
    【解决方案4】:

    在 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 会话。
    【解决方案5】:

    在 swift 3. 超时 15 秒。

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

    【讨论】:

    • 这并不能解释timeoutIntervalForRequesttimeoutIntervalForResource 之间的区别。
    【解决方案6】:

    对于 Swift 4:

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

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

    【讨论】:

      【解决方案7】:

      在我的情况下,我增加了错误课程的超时时间。我的超时错误通过增加 URLRequest 而不是 URLSession

      的超时得到解决
      var request = URLRequest(url: url)
      request.timeoutInterval = 30
      

      【讨论】:

      • 这就是为我解决超时问题的原因。我希望这需要与上述设置结合使用。
      猜你喜欢
      • 2016-05-27
      • 1970-01-01
      • 2013-01-23
      • 2021-06-24
      • 1970-01-01
      • 2021-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多