Request Timeout NSURLSession

孤街浪徒 提交于 2020-01-23 12:39:17

问题


hello I used this below code to send a request to Server. How can I add the timeout in this function

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
    }

I did some search too and I came to know about to use this function

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

instead of this

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

But problem is If I used the above function then I can't set these variables

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

Please anyone suggest me correct solution of how to add timeout in my function


回答1:


You can't modify your request because for some reason you went with immutable option. Since NSMutableURLRequest is a subclass of NSURLRequest you can use the very same initializer init(URL:cachePolicy:timeoutInterval:) to create an mutable instance and set default timeout. And then configure (mutate) this request as you need.

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



回答2:


NSMutableRequest has a property timeoutInterval which you can set. Here is Apple's documentation which shows you how to set a timeout.

They have stated

If during a connection attempt the request remains idle for longer than the timeout interval, the request is considered to have timed out. The default timeout interval is 60 seconds.

Please note that the timeout does not guarantee that the network call will get terminated if the network call does not complete within the timeout.

ie: Suppose you set the timeout to 60 seconds. The connection might still be active and not terminate after 60 seconds. The timeout occurs if there is no data transfer during a complete period of 60 seconds.

E.g. Consider the following scenario This does NOT incur a timeout

  • t=0 to t=59 seconds => No data transfers (Total of 59 seconds)
  • t=60 to t=62 => Some data arrives at t=60s (Total of 2 seconds)
  • t=63 to t=100 => No data transfers (Total of 37 seconds)
  • t=100 to t=260 => Remaining data transfers and completes the network request (Total of 160 seconds)

Now consider the following scenario. Timeout occurs at t=120

  • t=0 to t=59 seconds => Some data transfers until t=59 (Total of 59 seconds)
  • t=60 to t=120 => No data transfers (Total of 60 seconds)



回答3:


Use NSURLSessionConfiguration to specify the Timeout,

let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
sessionConfig.timeoutIntervalForRequest = 30.0 //Request Timeout interval 30 sec
sessionConfig.timeoutIntervalForResource = 30.0 //Response Timeout interval 30 sec

let session  = NSURLSession(configuration: sessionConfig)



回答4:


NSMutableURLRequest has this method too:

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


来源:https://stackoverflow.com/questions/35426981/request-timeout-nsurlsession

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!