How to make a synchronous request using Alamofire?

I am trying to execute a synchronous request using Alamofire . I looked through Stackoverflow and found this question: makes an asynchronous alamofire request synchronous .

I saw that the accepted answer uses completion to make the Alamofire request synchronous, but I cannot get it to work. This is my simplified code:

 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) } 

With this code, I get an error when I try to complete completion(bool value) . The error I am getting is the following:

Cannot call value of non-function type "Bool"

I tried using a lot of examples, using completion to get the values โ€‹โ€‹synchronously (because I need to get the data earlier to show it on the table and at the same time get the number of rows of this table) without success.

How can I use this completion to get a synchronous response?

Thanks in advance!

+7
ios swift synchronous alamofire
source share
2 answers

when you use a completion handler, do not use return.

 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 }) 

or if you want to return some value in the closure, you should use the completion handler to return some value or something, for example, if you want to return a boolean:

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

and in loadData

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

or some think differently.

I use swift 3. but if you want another version to quickly pay attention to the names of external parameters and the names of internal parameters, for example: @escaping (_ number: Int, _ strArr1: [String], _ strArr2: [String], _ strArr3: [String]) -> ())

if you want to set the names of external parameters, you just need to remove _ and set a name for the parameters.

+1
source share

Please note that Apple does not recommend making synchronous requests, for the reasons noted here .

In this example, I simplify the call if you have additional information, such as the contents of the cells, I suggest you take a look at SwiftyJSON and return the entire JSON Blob, and then parse it in the appropriate methods (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) } } 
0
source share

All Articles