[英]NSURLConnection sendAsynchronousRequest can't get variable out of closure
I'm trying to get a simple text response from a PHP page using POST. 我正在尝试使用POST从PHP页面获得简单的文本响应。 I have the following code:
我有以下代码:
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
}
While this code does not throw any errors, when I make a call to it like this: 虽然这段代码不会引发任何错误,但是当我这样调用它时:
println(post(url, info: data))
It only prints: "Nothing Returned" even though if I were to change the line: 即使我更改了该行,它也只会打印:“什么也没返回”:
output = (NSString(data: data, encoding: NSUTF8StringEncoding))!
to this: 对此:
println((NSString(data: data, encoding: NSUTF8StringEncoding)))
it does print out the proper response. 它确实打印出正确的响应。 Am I doing something wrong with my variables here?
我的变量在这里做错了吗?
This is calling asynchronous function that is using a completion handler block/closure. 这正在调用使用完成处理程序块/关闭的异步函数。 So, you need to employ the completion handler pattern in your own code.
因此,您需要在自己的代码中使用完成处理程序模式。 This consists of changing the method return type to
Void
and adding a new completionHandler
closure that will be called when the asynchronous call is done: 这包括将方法返回类型更改为
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)
}
}
Or, since NSURLConnection
is now formally deprecated, it might be better to use 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
}
And you call it like so: 您这样称呼它:
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)
Note, to keep this simple, I've employed the trailing closure syntax (see Trailing Closure section of The Swift Programming Language: Closures ), but hopefully it illustrates the idea: You cannot immediately return the result of an asynchronous method, so provide a completion handler closure that will be called when the asynchronous method is done. 注意,为简单起见,我采用了尾随闭包语法(请参见Swift编程语言:Closures的 尾随闭包部分),但希望它能说明这一思想:您不能立即返回异步方法的结果,因此请提供一个完成处理程序关闭,将在异步方法完成后调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.