我正在尝试使用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)))
它确实打印出正确的响应。我的变量在这里做错了吗?
这是在调用使用完成处理程序块/关闭的异步函数。因此,您需要在自己的代码中使用完成处理程序模式。这包括将方法的返回类型更改为,Void并添加一个新的completionHandler闭包,该闭包将在异步调用完成后被调用:
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:
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)
注意,为简单起见,我采用了尾随闭包语法(请参见Swift编程语言:Closures的 尾随闭包 部分),但希望它能说明这一思想:您不能立即返回异步方法的结果,因此请提供一个完成处理程序关闭,将在异步方法完成后调用。