Проблема в том, что callWebAPI
является асинхронным (возвращается сразу перед выполнением запроса), поэтому вы немедленно вызываете leave
.Вы можете дать этому методу обработчик завершения и вызвать в нем leave
.И вы бы также вызывали обновление пользовательского интерфейса в блоке notify
для своей группы, а не просто отправляли его.
Проще, просто полностью удалите DispatchGroup
и просто обновите свой пользовательский интерфейс в обработчике завершения, который вы предоставляетеcallWebAPI
.
Например, дать callWebAPI
обработчик завершения:
func callWebAPI(completionHandler: @escaping ([[String: Any]]?, Error?) -> Void) {
let urlString = URL(string: "https://restcountries.eu/rest/v2/all")
if let url = urlString {
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
do {
let jsonResponse = try JSONSerialization.jsonObject(with:
data)
completionHandler(jsonResponse as? [[String: Any]], nil)
} catch let parsingError {
completionHandler(nil, parsingError)
}
}
task.resume()
}
}
И затем вы можете исключить группы отправки, глобальные очереди (поскольку это уже асинхронный методвам не нужно вызывать это из фоновой очереди), и т. д., и это просто:
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
callWebAPI { jsonResponse, error in
guard let jsonResponse = jsonResponse, error == nil else {
print("Error:", error ?? "Response was not correct format")
return
}
print(jsonResponse)
// Note, you don’t appear to be using `jsonResponse` at all,
// so I presume you’d update the relevant model objects.
DispatchQueue.main.async {
self.filteredCountry = self.arrCountry.filter({$0.name.prefix(searchText.count) == searchText})
self.searching = true
self.tableView.reloadData()
}
}
}
В настоящее время мы используем JSONDecoder
для анализа JSON для заполнениямоделировать объекты напрямую, но это выходит за рамки этого вопроса.