我正在尝试使用Open Weather API构建天气预报应用程序,在我的预测类中,我有以下结构类型。
struct ForecastWeather {
public private(set) var date: String
public private(set) var weatherDetails: [WeatherInfo]
}
struct WeatherInfo {
public private(set) var weatherImage: String
public private(set) var time: String
public private(set) var weatherType: String
public private(set) var temperature: String
}
我需要使用二维数组,因为在我的表视图中有预测数据的部分。我将对象放入var forecastWeathers = [ForecastWeather]()
数组中。
ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0")])
ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0")])
ForecastWeather(date: "Thursday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "01n", time: "18:00", weatherType: "Clear", temperature: "21.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10n", time: "00:00", weatherType: "Rain", temperature: "13.0")])
ForecastWeather(date: "Friday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "03:00", weatherType: "Rain", temperature: "14.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "12:00", weatherType: "Rain", temperature: "19.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "10d", time: "15:00", weatherType: "Rain", temperature: "19.0")])
ForecastWeather(date: "Monday", weatherDetails: [WeatherForecast.WeatherInfo(weatherImage: "03n", time: "18:00", weatherType: "Clouds", temperature: "16.0")])
在我的表格视图中,我需要像WeatherService.instance.forecastWeathers[indexPath.section].weatherDetails[indexPath.row]
一样将这些部分放入其中。它现在给我一个错误,因为我里面有3个相同的星期四对象。如何映射或过滤仅包含日期信息的forecastWeathers
数组,因为我有多个部分,我尝试使用地图功能,但我无法成功。
此处编辑是我的API调用
let json = JSON(value)
for i in 0..<json["list"].count {
let icon = json["list"][i]["weather"][0]["icon"].stringValue // Image icon
let date = self.convertUnixDate(fromDoubleTo: json["list"][i]["dt"].doubleValue)
let weatherType = json["list"][i]["weather"][0]["main"].stringValue.capitalized
let temperature = "\(self.temperatureConverter(kelvinTo: json["list"][i]["main"]["temp"].doubleValue))"
let time = self.convertTime(timeArr: json["list"][i]["dt_txt"].stringValue)
let forecastObj = ForecastWeather(date: date, weatherDetails: [WeatherInfo(weatherImage: icon, time: time, weatherType: weatherType, temperature: temperature)])
print(forecastObj)
self.forecastWeathers.append(forecastObj)
}
还有API结果5 day forecast
这是我的表格视图委托方法
func numberOfSections(in tableView: UITableView) -> Int {
return WeatherService.instance.newForecastWeathers.count
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return WeatherService.instance.newForecastWeathers[section].date.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = forecastTableView.dequeueReusableCell(withIdentifier: cellId) as? ForecastCell else { return ForecastCell() }
cell.configureCell(weatherDetails: WeatherService.instance.newForecastWeathers[indexPath.section].weatherDetails[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = .orange
let label = UILabel()
label.text = WeatherService.instance.newForecastWeathers[section].date
label.frame = CGRect(x: 45, y: 5, width: 100, height: 35)
view.addSubview(label)
return view
}
答案 0 :(得分:1)
问题在于您没有将内部weatherDetails
用作数组,因为您始终只添加一个元素。
因此,您必须将属于同一天的WeatherInfo
添加到该数组,可能就是这样:
struct ForecastWeather {
public private(set) var date: String
public private(set) var weatherDetails = [WeatherInfo]()
public init (date:String) {
self.date = date
}
public mutating func addInfo(_ info:WeatherInfo) {
weatherDetails.append(info)
}
}
struct WeatherInfo {
public private(set) var weatherImage: String
public private(set) var time: String
public private(set) var weatherType: String
public private(set) var temperature: String
}
var thursday = ForecastWeather(date: "Thursday")
thursday.addInfo(WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0"))
thursday.addInfo(WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0"))
var friday = ForecastWeather(date: "Friday")
friday.addInfo(WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0"))
// ...
let forecastWeathers = [thursday, friday /* ... */]
答案 1 :(得分:1)
我已修复了一些错误,并允许公开weatherDetails
以简化附加操作。这是一种功能风格。随着排序。
//: Playground - noun: a place where people can play
struct ForecastWeather {
public private(set) var date: String
public var weatherDetails: [WeatherInfo]
public var index: Int {
return ForecastWeather.weekdays[date] ?? 0
}
private static let weekdays: [String: Int] = ["Sunday": 0, "Monday": 1, "Thuesday": 2, "Wednesday": 3, "Thursday": 4, "Friday": 5, "Saturday": 6]
}
struct WeatherInfo {
public private(set) var weatherImage: String
public private(set) var time: String
public private(set) var weatherType: String
public private(set) var temperature: String
}
var forecastWeathers = [ForecastWeather]()
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "01d", time: "12:00", weatherType: "Clear", temperature: "35.0")]))
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "02d", time: "15:00", weatherType: "Clouds", temperature: "31.0")]))
forecastWeathers.append(ForecastWeather(date: "Thursday", weatherDetails: [WeatherInfo(weatherImage: "01n", time: "18:00", weatherType: "Clear", temperature: "21.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "03n", time: "21:00", weatherType: "Clouds", temperature: "16.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "10n", time: "00:00", weatherType: "Rain", temperature: "13.0")]))
forecastWeathers.append(ForecastWeather(date: "Friday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "03:00", weatherType: "Rain", temperature: "14.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "12:00", weatherType: "Rain", temperature: "19.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "10d", time: "15:00", weatherType: "Rain", temperature: "19.0")]))
forecastWeathers.append(ForecastWeather(date: "Monday", weatherDetails: [WeatherInfo(weatherImage: "03n", time: "18:00", weatherType: "Clouds", temperature: "16.0")]))
var storedForecastWeatherIndicies: [String: ForecastWeather] = [:]
forecastWeathers.forEach { value in
guard storedForecastWeatherIndicies[value.date] == nil else {
// if is already found
storedForecastWeatherIndicies[value.date]?
.weatherDetails
.append(contentsOf: value.weatherDetails)
return
}
// if a new value for the Dictinary
storedForecastWeatherIndicies[value.date] = value
}
let result = storedForecastWeatherIndicies.values.map { $0 }.sorted { first, second in first.index < second.index }
print(result)
[__ lldb_expr_7.ForecastWeather(日期:&#34;星期一&#34;,weatherDetails: [__lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 12:00&#34;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 19.0&#34;), __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 15:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 19.0&#34; ) __lldb_expr_7.WeatherInfo(weatherImage:&#34; 03n&#34;,time:&#34; 18:00&#34 ;, weatherType:&#34; Clouds&#34 ;, temperature:&#34; 16.0&#34; )]), __lldb_expr_7.ForecastWeather(日期:&#34;星期四&#34;,weatherDetails:[__ lldb_expr_7.WeatherInfo(weatherImage:&#34; 01d&#34;,时间:&#34; 12:00&#34;, weatherType:&#34; Clear&#34 ;, temperature:&#34; 35.0&#34;), __lldb_expr_7.WeatherInfo(weatherImage:&#34; 02d&#34;,time:&#34; 15:00&#34 ;, weatherType:&#34; Clouds&#34 ;, temperature:&#34; 31.0&#34; ) __lldb_expr_7.WeatherInfo(weatherImage:&#34; 01n&#34;,time:&#34; 18:00&#34 ;, weatherType:&#34; Clear&#34 ;, temperature:&#34; 21.0&#34; )]), __lldb_expr_7.ForecastWeather(日期:&#34;星期五&#34;,weatherDetails:[_ _ lldb_expr_7.WeatherInfo(weatherImage:&#34; 03n&#34;,time:&#34; 21:00&#34;, weatherType:&#34;云&#34;,温度:&#34; 16.0&#34;), __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10n&#34;,time:&#34; 00:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 13.0&#34; ) __lldb_expr_7.WeatherInfo(weatherImage:&#34; 10d&#34;,time:&#34; 03:00&#34 ;, weatherType:&#34; Rain&#34 ;, temperature:&#34; 14.0&#34; )])]
修改强>
这是不正确的:date.count
是你的字符串的长度。不是数组
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return WeatherService.instance.newForecastWeathers[section].date.count
}
使用weatherDetails
代替
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return WeatherService.instance.newForecastWeathers[section].weatherDetails.count
}