当我将数据发布到服务时,请求通常很好,但是如果它需要太长时间并且超时,则在完成处理程序中,我将NSURLResponse设置为nil,即使它永远不会返回nil。
我正在使用Swift 1.1,这是我如何做到这一点的一个例子:
func postX(actionKey:String, postData:AnyObject, callBack:((data:NSData?, resp: NSURLResponse) -> Void)?) -> Void
{
var mreq = createRequest(actionKey, method: "POST", https: true, json: true)
if (self.dataTask != nil)
{
self.dataTask?.cancel()
}
var err: NSError?
mreq.HTTPBody = NSJSONSerialization.dataWithJSONObject(postData, options: nil, error: &err)
self.dataTask = self.getSession().dataTaskWithRequest(mreq, completionHandler: { (data:NSData!, resp: NSURLResponse!, error: NSError!) -> Void in
Dlog.log("response: \(resp)") //Prints out: response: nil
if (error != nil)
{
//do something
}
else
{
//do something else
}
})
if (self.dataTask != nil)
{
self.dataTask!.resume()
}
}
答案 0 :(得分:3)
NSURLResponse
completionHandler
块中的dataTaskWithRequest
引用是可选的(意味着它可以为nil
)。如果请求超时,您希望它是nil
(因为您可能尚未收到任何回复)。
我建议您将NSURLResponse
闭包的callback
参数更改为可选,就像dataTaskWithRequest
一样。 (我也可能会返回可选的NSError
,因此您可以检查特定错误。)并且您可以通过查找NSURLErrorTimedOut
来检测超时错误。
例如:
func postX(actionKey: String, postData: AnyObject, callBack: (NSData?, NSURLResponse?, NSError?) -> ()) {
let request = createRequest(actionKey, method: "POST", https: true, json: true)
dataTask?.cancel() // note, we don't need `if` clause, as the `?` does everything for us
request.HTTPBody = try! NSJSONSerialization.dataWithJSONObject(postData, options: [])
let task = getSession().dataTaskWithRequest(request) { data, response, error in
callBack(data, response, error)
}
task.resume()
dataTask = task
}
然后你就可以使用它:
postX(actionKey, postData: postData) { data, response, error in
// handle response however you want
// did it time out?
if error?.domain == NSURLErrorDomain && error?.code == NSURLErrorTimedOut {
print("timed out") // note, `response` is likely `nil` if it timed out
}
}
为了完整起见,Swift 3实现可能如下所示:
func postX(actionKey: String, postData: AnyObject, callBack: (Data?, URLResponse?, NSError?) -> ()) {
var request = createRequest(actionKey: actionKey, method: "POST", https: true, json: true)
dataTask?.cancel() // note, we don't need `if` clause, as the `?` does everything for us
request.httpBody = try! JSONSerialization.data(withJSONObject: postData, options: [])
let task = getSession().dataTask(with: request) { data, response, error in
callBack(data, response, error)
}
task.resume()
dataTask = task
}
func createRequest(actionKey: String, method: String, https: Bool, json: Bool) -> URLRequest {
var request = URLRequest(url: ...)
...
return request
}
它会被称为:
postX(actionKey: actionKey, postData: postData) { data, response, error in
// handle response however you want
// did it time out?
if error?.domain == NSURLErrorDomain && error?.code == NSURLErrorTimedOut {
print("timed out") // note, `response` is likely `nil` if it timed out
}
}