#swift #xcode #api #closures
#быстрый #xcode #API #закрытие
Вопрос:
Я получаю результат API в своей модели представления, как показано ниже:
class HomePageViewModel { var apiResult: CountryDataFromAPI? //Getting API result via viewModel public func getAPIResult(withOffset: Int, completion: @escaping () -gt; Void) { APIHandler.urlRequest(with: withOffset) { result in self.apiResult?.data.append(contentsOf: result.data) print("api resultdata in viewmodel is (result.data)") completion() } } }
Получение api работает нормально. В приведенном выше коде я могу распечатать инструкцию как print(«api resultdata в viewmodel is (result.data)») и увидеть ожидаемый результат api.
Когда я получаю данные внутри своей модели представления, как указано выше, я использую их в своем MainViewController.
Мой MainViewController инициализируется с помощью ViewModel
class HomePageViewController: UIViewController { private var viewModel : HomePageViewModel private var countryDataArray: [CountryData]? init(with viewModel: HomePageViewModel) { self.viewModel = viewModel super.init(nibName: nil, bundle: nil) } }
Все работает нормально, пока я не попытаюсь получить данные из ViewModel, как показано ниже. Я пытаюсь установить данные в ViewModel в параметр под названием countryDataArray. Но при этом внутри закрытия мое заявление о печати «print(«данные в vc (self?.ViewModel.apiResult?.данные)»)» выводит ноль, даже если он получает данные в ViewModel.
override func viewDidLoad() { super.viewDidLoad() //Getting API Result in viewDidLoad. And after getting the result, reloading the tableView. self.viewModel.getAPIResult(withOffset: 11) { [weak self] in DispatchQueue.main.asyncAfter(deadline: .now() 2, execute: { self?.countryDataArray = self?.viewModel.apiResult?.data print("data in vc is (self?.viewModel.apiResult?.data)") self?.countriesListTableView.reloadData() }) } }
Почему это может происходить?
PS: Мои модели api следующие:
struct CountryDataFromAPI: Codable { var data: [CountryData] } struct CountryData: Codable,Equatable { let name : String let code: String let wikiDataId: String }
Комментарии:
1. Вы использовали отладчик, чтобы определить, какая часть
self?.viewModel.apiResult?.data
на самом деле равна нулю? Это может бытьself
илиapiResult
.2. apiResult выглядит как ноль, но в нем есть данные внутри ViewModel. Поскольку я инициализирую ViewController с помощью этой модели представления, я ожидаю, что в ней будут данные внутри модели представления.
Ответ №1:
На мой взгляд, проблема заключается в self.apiResult?.data.append(contentsOf: result.data)
Вы не присвоили никакого значения для apiResult.data. Потому что apiResult равен нулю.
Вы должны инициализировать apiResult после получения данных из API.
Комментарии:
1. Я согласен с этим, но также утверждаю, что нет смысла хранить весь результат вызова API, если используется только
data
он. Так что, может быть, измените его наvar apiResult: [CountryData]
. Затем это свойство и то же свойство контроллера представления можно сделать необязательными и инициализировать как пустые массивы.2. Вы оба совершенно правы. Когда я инициализировал apiResult как var apiResult: [Данные страны] = [], это сработало. Не могли бы вы, пожалуйста, рассказать мне, в чем проблема и почему она не работает с опционными предложениями? После добавления данных в необязательный массив я не инициализирую его данными?