问题
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