【问题标题】:Request Timeout NSURLSession请求超时 NSURLSession
【发布时间】:2016-05-27 09:40:11
【问题描述】:

你好,我使用下面的代码向服务器发送请求。如何在此函数中添加超时

static func postToServer(url:String,var params:Dictionary<String,NSObject>, completionHandler: (NSDictionary?, String?) -> Void ) -> NSURLSessionTask {


        let request = NSMutableURLRequest(URL: NSURL(string: url)!)


        let session = NSURLSession.sharedSession()

        request.HTTPMethod = "POST"

    if(params["data"] != "get"){
        do {

            let data = try NSJSONSerialization.dataWithJSONObject(params, options: .PrettyPrinted)

            let dataString = NSString(data: data, encoding: NSUTF8StringEncoding)!
            print("dataString is  \(dataString)")

            request.HTTPBody = data


        } catch {
            //handle error. Probably return or mark function as throws
            print("error is \(error)")
            //return
        }

    }
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

        let task = session.dataTaskWithRequest(request) {data, response, error -> Void in
            // handle error

            guard error == nil else { return }
            request.timeoutInterval = 10


           print("Response: \(response)")
            let strData = NSString(data: data!, encoding: NSUTF8StringEncoding)
             completionHandler(nil,"Body: \(strData!)")
          //print("Body: \(strData!)")

            let json: NSDictionary?
            do {
                json = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableLeaves) as? NSDictionary
            } catch let dataError {
                // Did the JSONObjectWithData constructor return an error? If so, log the error to the console
                print(dataError)
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
              print("Error could not parse JSON: '\(jsonStr)'")
                completionHandler(nil,"Body: \(jsonStr!)")

                // return or throw?
                return
            }


            // The JSONObjectWithData constructor didn't return an error. But, we should still
            // check and make sure that json has a value using optional binding.
            if let parseJSON = json {
                // Okay, the parsedJSON is here, let's get the value for 'success' out of it

                completionHandler(parseJSON,nil)
                //let success = parseJSON["success"] as? Int
                //print("Succes: \(success)")
            }
            else {
                // Woa, okay the json object was nil, something went worng. Maybe the server isn't running?
                let jsonStr = NSString(data: data!, encoding: NSUTF8StringEncoding)
                print("Errors could not parse JSON: \(jsonStr)")
                completionHandler(nil,"Body: \(jsonStr!)")
            }

        }

        task.resume()
        return task
    }

我也搜索了一下,才知道要使用这个功能

let request = NSURLRequest(URL: url!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)

而不是这个

let request = NSMutableURLRequest(URL: NSURL(string: url)!)

但问题是如果我使用上述函数,那么我无法设置这些变量

request.HTTPBody = data
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")

请任何人建议我如何在我的函数中添加超时的正确解决方案

【问题讨论】:

    标签: ios swift nsurlconnection nsurl nsurlsession


    【解决方案1】:

    您无法修改您的请求,因为出于某种原因您选择了不可变选项。由于 NSMutableURLRequest 是 NSURLRequest 的子类,您可以使用相同的初始化程序 init(URL:cachePolicy:timeoutInterval:) 创建一个 mutable 实例并设置默认超时。然后根据需要配置(变异)此请求。

    let request = NSMutableURLRequest(URL: url!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5.0)
    

    【讨论】:

    • 好的,谢谢。它的工作。我想问的最后一个问题是如何将 nil 返回给我的调用函数。我正在这样做 if(response == nil){ completionHandler(nil,"nil") 但它不起作用
    【解决方案2】:

    NSMutableRequest 有一个属性 timeoutInterval 可以设置。 Here 是 Apple 的文档,它向您展示了如何设置超时。

    他们已经声明了

    如果在连接尝试期间请求保持空闲的时间超过超时间隔,则认为该请求已超时。默认超时间隔为 60

    请注意,超时确实保证如果网络调用会终止网络调用strong> 在超时时间内完成。

    ie:假设您将超时设置为 60 秒。 连接可能仍处于活动状态,并且在 60 秒后不会终止。如果在整个 60 秒内没有数据传输,则会发生超时。

    例如考虑以下情况 这不会导致超时

    • t=0 到 t=59 秒 => 无数据传输(总共 59 秒)
    • t=60 到 t=62 => 一些数据在 t=60s 到达 (总共 2 秒)
    • t=63 到 t=100 => 无数据传输(总共 37 秒)
    • t=100 到 t=260 => 剩余数据传输并完成网络 请求(总共 160 秒)

    现在考虑以下场景超时发生在 t=120

    • t=0 到 t=59 秒 => 一些数据传输到 t=59 (总共 59 秒)
    • t=60 到 t=120 => 无数据传输(总共 60 秒)

    【讨论】:

      【解决方案3】:

      使用NSURLSessionConfiguration指定超时时间,

      让 sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration() sessionConfig.timeoutIntervalForRequest = 30.0 //请求超时间隔30秒 sessionConfig.timeoutIntervalForResource = 30.0 //响应超时间隔30秒 让会话 = NSURLSession(配置:sessionConfig)

      【讨论】:

        【解决方案4】:

        NSMutableURLRequest 也有这个方法:

        let request = NSMutableURLRequest(URL:  NSURL(string: url)!, cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 5)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-02-25
          • 2014-06-19
          • 1970-01-01
          • 2015-12-06
          • 2011-02-26
          • 1970-01-01
          • 1970-01-01
          • 2017-02-22
          相关资源
          最近更新 更多