¿Cómo hacer una request síncrona con Alamofire?

Estoy intentando hacer una request síncrona usando Alamofire . He mirado Stackoverflow y he encontrado esta pregunta: hacer una request asincrónica de alamofire sincrónica .

Vi que la respuesta aceptada utiliza la completion para que Alamofire solicite sincronía, pero no puedo hacerlo funcionar. Este es mi código simplificado:

 func loadData(completion: (Bool)) -> (Int, [String], [String], [String]){ Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in switch(response.result) { case .success(_): if let JSON = response.result.value as! [[String : AnyObject]]!{ //Here I retrieve the data } completion(true) break case .failure(_): print("Error") completion(false) break } } return (numberRows, nameArray, ageArray, birthdayArray) } 

Con este código obtengo un error al intentar completion(bool value) . El error que obtengo es el siguiente:

No se puede llamar al valor de tipo no funcional 'Bool'

He intentado usar muchos ejemplos utilizando la finalización para get los valores sincrónicamente (porque necesito recuperar los datos antes para mostrarlos en una tabla y al mismo time get el número de filas de esa tabla) sin éxito.

¿Cómo puedo usar esa finalización para get una respuesta síncrona?

¡Gracias por adelantado!

cuando utiliza el manejador de finalización, no use retorno.

 func loadData(completion: @escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ()){ Alamofire.request(url!, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: nil).responseJSON { response in switch(response.result) { case .success(_): if let JSON = response.result.value as! [[String : AnyObject]]!{ //Here I retrieve the data } completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray) break case .failure(_): print("Error") completion(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray) break } } } loadData (completion: { (number, strArr1, strArr2, strArr3) in // do it // for exapmple self.number = number self.strArr1 = strArr1 // and so on }) 

o si desea devolver cualquier valor en el cierre, debe usar el manejador de finalización para devolver cualquier valor o algo así, por ejemplo, si desea devolver el valor boolean:

 func loadData(completion:(number: numberRows, strArr1 : nameArray, strArr2 : ageArray, strArr3: birthdayArray) -> (Bool)) 

y en loadData

 loadData( completion: { ( number, strArr1, strArr2, strArr3 ) -> (Bool) in # code return False }) 

o algunos piensan más.

Utilizo swift 3. pero si quieres otra versión de rápido cuidado sobre los nombres de parameters externos y los nombres de los parameters internos, como: @escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ())

si desea establecer nombres de parameters externos, solo necesita soltar _ y establecer el nombre de los parameters.

Tenga en count que hacer requestes síncronas es muy desalentado por Apple, por las razones que se señalan aquí .

En este ejemplo, estoy simplificando la llamada, si tiene más información, como el contenido de las celdas, le sugiero que mire SwiftyJSON y devuelva todo JSON Blob, luego lo analice en los methods relevantes (numberOfRows, etc. .)

 class TableViewJSONAsynchCalls: UIViewController, UITableViewDelegate, UITableViewDataSource { var tableView = UITableView() var numberOfRows = 0; override func viewDidLoad() { loadData { (didCompleteRequest) in if (didCompleteRequest) { tableView.delegate = self tableView.dataSource = self tableView.reloadData() } else { // Handle error if data was not loaded correctly } } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numberOfRows; } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { return UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell") } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { print("selected") } func loadData(completion: (Bool) -> Void) { // Make asynchronous call using alamofire // This simulates you parsing the JSON and setting the relevant variables, // personally I would recommend you return a JSON blob and then // parse it in the relevant methods. sleep(2) // If call is successful self.numberOfRows = 10 completion(true) } }