ios - NSURLConnection sendAsynchronousRequest 无法从闭包中获取变量

标签 ios post asynchronous swift nsurlconnection

我正在尝试使用 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))

它只打印:“Nothing Returned”,即使我要更改行:

output = (NSString(data: data, encoding: NSUTF8StringEncoding))!

对此:

println((NSString(data: data, encoding: NSUTF8StringEncoding)))

它确实打印出正确的响应。我在这里的变量做错了什么吗?

最佳答案

这是调用使用完成处理程序 block /闭包的异步函数。因此,您需要在自己的代码中使用完成处理程序模式。这包括将方法返回类型更改为 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: ClosuresTrailing Closure 部分),但希望它说明了这个想法:您无法立即返回一个异步方法,因此提供一个完成处理程序闭包,该闭包将在异步方法完成时调用。

关于ios - NSURLConnection sendAsynchronousRequest 无法从闭包中获取变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34716440/

相关文章:

java - HTTP客户端408状态码

javascript - jQuery:立即调用 when() done() 数组中的函数

javascript - 并行 API 请求的异步模块错误

ios - 更新发布在air 3.5?

iphone - 使用仪器时未找到此可执行文件的有效配置文件错误

ios - Clueful如何获取所有已安装的iOS应用程序的列表?

python - 从 BaseHTTPServer 解析 Python HTML POST 数据

c++ - POST HTTP 请求以使用 Java 脚本和 C++ 使用用户名和密码登录

mysql - 为不同的 id sqlite 选择前 1 行

javascript - 未定义模块名称 - node js