首页 > 解决方案 > URLSession.shared.uploadTask 完成后继续代码

问题描述

我正在尝试使用命令“uploadTask”与 Swift 通信到 php 网站。该站点正在发回数据,这运行良好。来自网站的结果存储在变量“answer”中。但是在uploadTask.resume() 完成之后,我如何才能真正使用“答案”呢?

运行文件时,它总是打印:“一”然后“三”然后“二”。

我知道我可以在 "print("two")" 部分所在的地方用 "answer" 来做事。在许多示例中,使用了命令“DispatchQueue.main.async { ... }”。但我明确想完成uploadTask,然后继续进行更多计算。

   func contactPHP() {

    print("One")

    let url = "http://....php" // website to contact
    let dataString = "password=12345" // starting POST
    let urlNS = NSURL(string: url)
    var request = URLRequest(url: urlNS! as URL)
    request.httpMethod = "POST"
    let dataD = dataString.data(using: .utf8) // convert to utf8 string

    URLSession.shared.uploadTask(with: request, from: dataD)
    {
        (data, response, error) in
        if error != nil {
            print(error.debugDescription)
        } else {
            let answer = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!
            print("Two")
        }
        }.resume()  // Starting the dataTask

  print("Three")

 // Do anything here with "answer"

}

extension NSMutableData {
    func appendString(string: String) {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        append(data!)
    }
}

我已经用完成处理程序试过了。但这也不起作用。这也给了我“一”、“四”、“二”、“三”

func test(request: URLRequest, dataD: Data?, completion: @escaping (NSString) -> ()) {
    URLSession.shared.uploadTask(with: request, from: dataD)
    {
        (data, response, error) in
        if error != nil {
            print(error.debugDescription)
        } else {
            let answer = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!
            print("Two")
            completion(answer)
        }
        }.resume()  // Starting the dataTask
    }

let blubb = test(request: request, dataD: dataD) { (data) in
    print("Three")
}

print("Four")

标签: swiftnsurlsessionuploadtask

解决方案


使用URLSession具有完成处理程序的函数:

URLSession.shared.uploadTask(with: URLRequest, from: Data?, completionHandler: (Data?, URLResponse?, Error?) -> Void)

uploadTask用这样的东西替换你的函数:

URLSession.shared.uploadTask(with: request, from: dataD) { (data, response, error) in

     if let error = error {
          // Error
     }

     // Do something after the upload task is complete

}

苹果文档

创建任务后,您必须通过调用其 resume() 方法来启动它。如果请求成功完成,completion handler 块的 data 参数包含资源数据,error 参数为 nil。

如果请求失败,则 data 参数为 nil,error 参数包含有关失败的信息。如果接收到来自服务器的响应,无论请求是成功完成还是失败,响应参数都包含该信息。

上传任务完成后,调用该函数的完成处理程序。您还可以实现委托的optional func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)功能。


推荐阅读