Недавно застряла проблема назначения только что загруженных JSON данных в переменную источника данных табличного представления. Я полагаю, что проблема очевидна, но моего мастерства недостаточно, чтобы собрать общую картину. Позвольте мне поделиться кучей кода.
(1) Функция извлекает данные из API Open Weather Map (определено в отдельном классе 'GetWeather').
func getMowForecast(completion: @escaping ((WeatherForecast?, Bool)) -> Void) {
let url = URL(string: "http://api.openweathermap.org/data/2.5/forecast?id=524901&APPID=b3d57a41f87619daf456bfefa990fce4&units=metric")!
let request = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let data = data {
do {
let json = try JSONDecoder().decode(WeatherForecast.self, from: data)
completion((json, true))
} catch {
print(error)
completion((nil, false))
}
} else {
print(error)
}
}
task.resume()
}
Здесь все отлично работает. JSON загружается правильно и соответствует модели данных. Вот ссылка на JSON данные для отображения в tableView: https://pastebin.com/KkXwxYgS
(2) Контроллер обрабатывает отображение полученных JSON данных в формате tableView
import UIKit
class ForecastViewController: UITableViewController {
@IBOutlet weak var tableV: UITableView! // tableView outlet in the IB
let weatherGetter = GetWeather() // object to handle the JSON retrieval
var tableData: WeatherForecast? // tableView data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.tableData?.list.count ?? 0
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableVCCell
cell.dateLabel.text = "\(self.tableData?.list[indexPath.row].dt)"
cell.tempLabel.text = "\(self.tableData?.list[indexPath.row].main.temp)"
cell.feelsLikeLabel.text = "\(self.tableData?.list[indexPath.row].main.feels_like)"
return cell
}
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.navigationBar.prefersLargeTitles = true
tableV.delegate = self
tableV.dataSource = self
weatherGetter.getMowForecast { (data, status) in
if let data = data, status {
} else if status {
print("-------- Ошибка разбора данных прогноза погоды --------")
} else {
print("-------- Ошибка получения данных прогноза погоды --------")
}
self.tableData = data
print(self.tableData)
}
print(self.tableData?.list.count) // returns nil
self.tableData = weatherGetter.getMowForecast(completion: ((tableData, true))) // error - Cannot convert value of type '(WeatherForecast?, Bool)' to expected argument type '((WeatherForecast?, Bool)) -> Void'
}
}
Проблема в том, что табличное представление получает нулевой источник данных, поэтому оно не может загрузить данные и показывает пустой экран.
Я полагаю, ошибка находится в области действия - я пытаюсь получить данные JSON внутри функции, а они не go где-либо еще. Что меня интересует, так это то, почему назначение данных для self.tableData не оказывает никакого влияния?
Не могли бы вы помочь. Спасибо! Привет