Получение результата API с закрытием и передача его в другой ViewController

#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: [Данные страны] = [], это сработало. Не могли бы вы, пожалуйста, рассказать мне, в чем проблема и почему она не работает с опционными предложениями? После добавления данных в необязательный массив я не инициализирую его данными?