I need to make 2 API calls simultaneously. I have 2 URLs for the calls, and if one of the calls will return any error I want to stop all the code execution.
How I tried to do it:
I have a function called
performRequest()with a completion block. I call the function in myViewControllerto update the UI - show an error/or a new data if all was successful. Inside it I create aURLSessiontasks and then parse JSON:I created an array with 2 urls:
func performRequest(_ completion: @escaping (Int?) -> Void) { var urlArray = [URL]() guard let urlOne = URL(string: "https://api.exchangerate.host/latest?base=EUR&places=9&v=1") else { return } guard let urlTwo = URL(string: "https://api.exchangerate.host/2022-05-21?base=EUR&places=9") else { return } urlArray.append(urlOne) urlArray.append(urlTwo) }Then for each of the url inside the array I create a session and a task:
urlArray.forEach { url in let session = URLSession(configuration: .ephemeral) let task = session.dataTask(with: url) { data, _, error in if error != nil { guard let error = error as NSError? else { return } completion(error.code) return } if let data = data { let printData = String(data: data, encoding: String.Encoding.utf8) print(printData!) DispatchQueue.main.async { self.parseJSON(with: data) } } } task.resume() } print("all completed") completion(nil) }
For now I receive print("all completed") printed once in any situation: if both tasks were ok, if one of them was ok or none of them.
What I want is to show the print statement only if all tasks were completed successfully and to stop executing the code if one of them returned with error (for example if we will just delete one of the symbols in url string which will take it impossible to receive a data).
How can I do it correctly?
URLRequestinstead ofURLSessionand work with async/await? However, it works from iOS 15, not compatible with earlier versions.async awaitis available for iOS 13+ Meet async await show you how to implement the new api but also has samples on how it used to be done.