Swift 3 – Enviar hacer request de request sincrónica

Tengo el siguiente código:

func completeLoadAction(urlString:String) -> Int { let url = URL(string:urlString.trimmingCharacters(in: .whitespaces)) let request = URLRequest(url: url!) let task = URLSession.shanetworking.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error print("error=\(error)") let ac = UIAlertController(title: "Unable to complete", message: "The load has been added to the completion queue. This will be processed once there is a connection.", prefernetworkingStyle: .alert) ac.addAction(UIAlertAction(title: "OK", style: .default)) self.present(ac, animated: true) return } let httpStatus = response as? HTTPURLResponse var httpStatusCode:Int = (httpStatus?.statusCode)! let responseString = String(data: data, encoding: .utf8) print("responseString = \(responseString)") let ac = UIAlertController(title: "Completed Successfully", message: "The "+coldel+" has been completed successfully", prefernetworkingStyle: .alert) ac.addAction(UIAlertAction(title:"Continue", style: .default, handler: { action in self.performSegue(withIdentifier: "segueConfirmedLoad", sender: self) })) self.present(ac, animated: true) } task.resume() return httpStatusCode } 

Necesito poder llamar a este y al mismo time verificar el valor de retorno, ya que es el código de estado http, me avisará si la llamada fue exitosa o no.

El problema se debe a que está en un dataTask. No puedo acceder al código de estado de respuestas aquí.

 var httpStatusCode:Int = (httpStatus?.statusCode)! 

Porque la tarea no se inicia hasta que se llama a Task.Resume () y la tarea es asincrónica, por lo que nunca funcionará.

¿Hay alguna forma de evitar esto?

Siempre hay una forma de usar el patrón asynchronous.

Para hacer que la function sea asíncrona agregue un bloque de finalización

 func completeLoadAction(urlString:String, completion: (Int) -> ()) { let url = URL(string:urlString.trimmingCharacters(in: .whitespaces)) let request = URLRequest(url: url!) let task = URLSession.shanetworking.dataTask(with: request) { data, response, error in guard let data = data, error == nil else { // check for fundamental networking error print("error=\(error)") DispatchQueue.main.async { let ac = UIAlertController(title: "Unable to complete", message: "The load has been added to the completion queue. This will be processed once there is a connection.", prefernetworkingStyle: .alert) ac.addAction(UIAlertAction(title: "OK", style: .default)) self.present(ac, animated: true) } completion(0) // or return an error code return } let httpStatus = response as? HTTPURLResponse var httpStatusCode:Int = (httpStatus?.statusCode)! let responseString = String(data: data, encoding: .utf8) print("responseString = \(responseString)") DispatchQueue.main.async { let ac = UIAlertController(title: "Completed Successfully", message: "The "+coldel+" has been completed successfully", prefernetworkingStyle: .alert) ac.addAction(UIAlertAction(title:"Continue", style: .default, handler: { action in self.performSegue(withIdentifier: "segueConfirmedLoad", sender: self) })) self.present(ac, animated: true) } completion(httpStatusCode) } task.resume() } 

y llámelo así

 completeLoadAction(urlString: "www.something.com") { code in print(code) } 

Para hacerlo sincrónico y esperar puede usar semáforos como a continuación

 struct Login { static func execute() -> Bool { let request = NSURLRequest.... var success = false let semaphore = DispatchSemaphore(value: 0) let task = URLSession.shanetworking.dataTask(with: request, completionHandler: { _, response, error in if let error = error { print("Error while trying to re-authenticate the user: \(error)") } else if let response = response as? HTTPURLResponse, 300..<600 ~= response.statusCode { print("Error while trying to re-authenticate the user, statusCode: \(response.statusCode)") } else { success = true } semaphore.signal() }) task.resume() _ = semaphore.wait(timeout: DispatchTime.distantFuture) return success } }