Я пытаюсь создать приложение, которое ищет GitHub-репозитории. И я использую MVVM и Мойю. Когда я вызываю метод для поиска, я перезагружаю табличное представление прежде, чем сервер отвечает.
Итак, поток приложения должен быть:
Пользователь вводит поисковый запрос в строку поиска. В searchBarSearchButtonClicked(_:)
из SearchViewController
вызван мой метод поиска. Метод внутри SearchViewModel
. Итак, просмотр метода модели вызывает RepositoryService
, а затем NetworkService
.
Я поместил несколько операторов печати, чтобы увидеть порядок выполнения. И в консоли я получил: 2 3 4 (Here the table view is refreshing) 1
. Я пытался использовать GCD в разных местах, также я пытался использовать барьеры. В конце дня табличное представление все еще обновляется до вызова print(1)
.
SearchViewController:
extension SearchViewController: UISearchBarDelegate {
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
guard let query = searchBar.text, query.count > 2 else { return }
viewModel.searchRepositories(withQuery: query) { [weak self] in
guard let self = self else { return }
print(4)
print("Reloading...")
self.tableView.reloadData()
}
}
}
SearchViewModel:
var repositories = [Repository]()
func searchRepositories(withQuery query: String, completion: @escaping () -> Void) {
repositories = repositoryService.searchRepositories(withQuery: query)
print(3)
completion()
}
RepositoryService:
private var repositories = [Repository]()
func searchRepositories(withQuery query: String) -> [Repository] {
networkService?.searchRepositories(withQuery: query) { [weak self] repositories in
guard let self = self, let repositories = repositories else { return }
self.repositories += repositories
}
print(2)
return self.repositories
}
NetworkService:
func searchRepositories(withQuery query: String,
completionHandler: @escaping (([Repository]?) -> Void)) {
provider?.request(.searchRepo(query: query)) { result in
switch result {
case .success(let response):
do {
let repositories = try response.map(SearchResults<Repository>.self)
print(1)
completionHandler(repositories.items)
} catch let error {
print(error.localizedDescription)
}
case .failure(let error):
print(error)
}
}
}