Я создаю простое приложение с мировыми часами, которое извлекает данные о времени / дате и погоде из стороннего API-интерфейса. После декодирования данных json я сохраняю их в Core Data. Из базовых данных я создаю локальный массив (saveCities), который выступает в качестве источника данных для табличного представления.
Я написал функцию, которая извлекает самые последние данные о времени / дате / погоде и обновляет локальный массив (saveCities), но после перезагрузки таблицы он не обновляет все ячейки, ЕСЛИ БЕЗ сущности времени (которая является на самом деле строка) отличается ...
Пример: если я добавлю Окленд @ 12:41 вечера, а затем сразу добавлю Сидней @ 12:41 вечера, то обновляется только метка Сиднея, но метка Окленда пуста (см. картинка прилагается). Если я добавлю Окленд @ 12:41, а затем Сидней @ 12:42, тогда он корректно обновит обе метки.
Вот мой код для функции refreshData:
func refreshData() {
for city in savedCities {
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
let refreshUrl = "http://vip.timezonedb.com/v2.1/get-time-zone?key=\(apiKey)&format=json&by=city&city=\(city.cityName!)&country=\(city.countryCode!)"
let weatherUrl = "https://api.openweathermap.org/data/2.5/find?q=\(city.cityName!),\(city.countryCode!)&units=metric&appid=\(apiKey2)"
if let encodedWeatherUrl = URL(string: weatherUrl.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!) {
if let encodedRefreshUrl = URL(string: refreshUrl.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)!) {
// Refresh time an date
let refreshTask = session.dataTask(with: encodedRefreshUrl) { data, response, error in
// Check for errors
guard error == nil else {
print ("Refresh error: \(error!)")
return
}
// Check that data has been returned
guard let content = data else {
print("No data")
return
}
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let fetchedData = try decoder.decode(TimeZones.self, from: content)
if let data = fetchedData.zones?.first {
// Update time and date
city.formatted = data.formatted
city.formattedDate = data.formatted!.components(separatedBy: " ").first!
city.formattedTime = data.formatted!.components(separatedBy: " ").last!
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
} catch let err {
print("Refresh error", err)
}
}
// Refresh current weather
let weatherTask = session.dataTask(with: encodedWeatherUrl) { data, response, error in
// Check for errors
guard error == nil else {
print ("Weather error: \(error!)")
return
}
// Check that data has been returned
guard let content = data else {
print("No data")
return
}
// Decode data
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let currentWeatherData = try decoder.decode(Zone.Weather.self, from: content)
if let weather = currentWeatherData.list {
if let temp = weather.first?.main?.temp {
if let icon = weather.first?.weather?.first?.icon {
city.icon = icon
city.currentTemp = temp
}
}
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
} catch let err {
print("Weather error", err)
}
}
// execute the HTTP request
refreshTask.resume()
weatherTask.resume()
}
}
}
}
Вот мой код для обновления представления таблицы:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "timeZoneCell") as! TimeZoneCell
if isFiltering {
if let city = filteredCities[indexPath.row].cityName {
if let country = filteredCities[indexPath.row].countryName {
cell.cityName.text = "\(city.replacingOccurrences(of: "_", with: " ")), \(country)"
cell.cityDate.text = ""
cell.currentCityTime.text = ""
cell.currentTemp.text = ""
cell.weatherIcon.image = nil
}
}
} else {
let city = savedCities[indexPath.row]
if let city = city.cityName {
cell.cityName.text = "\(city)"
if let date = savedCities[indexPath.row].formattedDate {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
let formattedDate = formatter.date(from: date)
formatter.dateFormat = "EEE, d MMM"
let dateString = formatter.string(from: formattedDate!)
cell.cityDate.text = dateString
}
if let time = savedCities[indexPath.row].formattedTime {
let formatter = DateFormatter()
formatter.dateFormat = "HH:mm:ss"
let formattedTime = formatter.date(from: time)
formatter.dateFormat = "HH:mm"
let timeString = formatter.string(from: formattedTime!)
cell.currentCityTime.text = timeString
}
}
cell.currentTemp.text = String(city.currentTemp.rounded().formatted)
switch (city.icon) {
case "01d":
cell.weatherIcon.image = UIImage(named: "clearSky")
case "01n":
cell.weatherIcon.image = UIImage(named: "clearSky")
case "02d":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "02n":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "03d":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "03n":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "04d":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "04n":
cell.weatherIcon.image = UIImage(named: "scatteredClouds")
case "09d":
cell.weatherIcon.image = UIImage(named: "showerRain")
case "09n":
cell.weatherIcon.image = UIImage(named: "showerRain")
case "10d":
cell.weatherIcon.image = UIImage(named: "Rain")
case "10n":
cell.weatherIcon.image = UIImage(named: "Rain")
case "13d":
cell.weatherIcon.image = UIImage(named: "snow")
case "13n":
cell.weatherIcon.image = UIImage(named: "snow")
case "11d":
cell.weatherIcon.image = UIImage(named: "thunderstorm")
case "11n":
cell.weatherIcon.image = UIImage(named: "thunderstorm")
default:
break
}
}
return cell
}