我尝试使用POST从PHP页面获取简单的文本响应。我有以下代码:
func post(url: String, info: String) -> String {
var URL: NSURL = NSURL(string: url)!
var request:NSMutableURLRequest = NSMutableURLRequest(URL:URL)
var output = "Nothing Returned";
request.HTTPMethod = "POST";
var bodyData = info;
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()){
response, data, error in
output = (NSString(data: data, encoding: NSUTF8StringEncoding))!
}
return output
}
虽然这段代码不会引发任何错误,但是当我这样调用它时:
println(post(url, info: data))
它只打印:"没有返回"即使我要改变这条线:
output = (NSString(data: data, encoding: NSUTF8StringEncoding))!
到此:
println((NSString(data: data, encoding: NSUTF8StringEncoding)))
它打印出正确的响应。我这里的变量做错了吗?
答案 0 :(得分:9)
这是调用使用完成处理程序块/闭包的异步函数。因此,您需要在自己的代码中使用完成处理程序模式。这包括将方法返回类型更改为Void
并添加将在异步调用完成时调用的新completionHandler
闭包:
func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) {
let URL = NSURL(string: url)!
let request = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
let bodyData = info
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue()) { response, data, error in
guard data != nil else {
completionHandler(nil, error)
return
}
completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil)
}
}
或者,由于NSURLConnection
现已正式弃用,因此最好使用NSURLSession
:
func post(url: String, info: String, completionHandler: (NSString?, NSError?) -> ()) -> NSURLSessionTask {
let URL = NSURL(string: url)!
let request = NSMutableURLRequest(URL:URL)
request.HTTPMethod = "POST"
let bodyData = info
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
dispatch_async(dispatch_get_main_queue()) {
guard data != nil else {
completionHandler(nil, error)
return
}
completionHandler(NSString(data: data!, encoding: NSUTF8StringEncoding), nil)
}
}
task.resume()
return task
}
你这样称呼它:
post(url, info: info) { responseString, error in
guard responseString != nil else {
print(error)
return
}
// use responseString here
}
// but don't try to use response string here ... the above closure will be called
// asynchronously (i.e. later)
注意,为了保持这一点,我使用了尾随闭包语法(参见The Swift Programming Language: Closures的尾随关闭部分),但希望它说明了这个想法:你不能立即返回异步方法的结果,因此提供一个完成处理程序闭包,将在异步方法完成时调用。