Продолжить работу с кодом после завершения URLSession.shared.uploadTask.

Я пытаюсь связаться со Swift с php-сайтом, используя команду «uploadTask». Сайт отправляет данные обратно, и это работает хорошо. Результат с сайта сохраняется в переменной «ответ». Но как я могу использовать «ответ» ПОСЛЕ выполнения uploadTask.resume()?

При запуске файла всегда печатает: "Один", потом "три", потом "два".

Я знаю, что могу делать что-то с «ответом» прямо там, где находится раздел «печать («два»)». И во многих примерах тут же используется команда «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")

person highii    schedule 18.07.2019    source источник


Ответы (1)


Используйте функцию 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

}

Документация Apple

После того, как вы создадите задачу, вы должны запустить ее, вызвав ее метод возобновления(). Если запрос завершается успешно, параметр данных блока обработчика завершения содержит данные ресурса, а параметр ошибки равен нулю.

Если запрос завершается ошибкой, параметр данных равен нулю, а параметр ошибки содержит информацию об ошибке. Если ответ от сервера получен, независимо от того, успешно ли завершен запрос или нет, параметр ответа содержит эту информацию.

Когда задача загрузки завершена, вызывается обработчик завершения функции. Вы также можете реализовать функцию делегата optional func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data).

person Nathan    schedule 18.07.2019