有人能说出这里出了什么问题吗?
它向我发送此错误:类型"CityWeatherInfo"不符合协议"可编码">
struct CityWeatherInfo: Codable {
var name: String
var main: Main
var weathers: [Weather]
private enum CodingKeys: String, CodingKey {
case weathers = "weather"
case main = "main"
case name
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.name = try container.decode(String.self, forKey: .name)
let mainContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .main)
let weatherContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .weathers)
}
}
struct Weather: Decodable {
var main: String
var description: String
private enum WeatherKeys: String, CodingKey {
case main = "main"
case description = "description"
}
}
struct Main: Decodable {
var temp: Double
var feels_like: Double
var temp_min: Double
var temp_max: Double
private enum MainKeys: String, CodingKey {
case temp = "temp"
case feels_like = "feels_like"
case temp_min = "temp_min"
case temo_max = "temp_max"
}
}
Json是这样的:
{"coord":{"lon":-0.13,"lat":51.51},"天气":[{"id":804,"main":">云","描述":"阴云","图标":"04n"}],"基地":"站","main":{"temp":287.45,"feels_like":286.61,"temp_min":284.82,"temp_max":289.15,"压力":1012,"湿度":72},"能见度":10000,"风":{"速度":1,"度":0},"云":{"全部":100},"dt":1592362322,"sys":{"type":1,"id":1414,"国家":"GB","日出":1592365362,"日落":1592425222},"时区":3600,"id":2643743,"名称":"伦敦","cod":200}
如果结构或类采用Codable
则默认合成所需的方法init(from decoder: Decoder)
和encode(to encoder: Encoder)
。
但是,如果您自己实现其中一种方法,您也必须实现另一种方法。或者 - 在这种情况下 - 仅采用Decodable
,因为您只是读取/解码数据。
代码中存在一些不良做法。
-
自定义编码密钥
WeatherKeys
和MainKeys
毫无意义,因为在默认语法中,框架生成名为CodingKeys
的密钥。自定义键仅在自定义实现中考虑。 -
这两个
nestedContainers
都不需要,如果它们由相同的编码键键键,它们就没有意义。 -
如果字典键与结构成员名称匹配,则可以省略编码键。
-
如果不修改结构成员的值,则将它们声明为常量 (
let
(。 -
根据命名约定,变量应该被命名为lowerCamelCased。将snake_case转换为驼峰案例的一种便捷方法是指定
convertFromSnakeCase
密钥解码策略。
openweathermap
API 通过在 URL 中添加units=metric
来提供摄氏度的度数,或通过添加units=imperial
来提供华氏度。例如
https://api.openweathermap.org/data/2.5/weather?q=London&units=metric&appid=•••••••••••••"
UNIX 时间戳 (1592362322( 可以通过指定secondsSince1970
日期解码策略作为Date
解码
结构可以以这种简单的形式创建
struct CityWeatherInfo: Decodable {
let name: String
let main: Main
let weather: [Weather]
let dt : Date
}
struct Weather: Decodable {
let main: String
let description: String
}
struct Main: Decodable {
let temp, tempMin, tempMax, feelsLike : Double
}
并使用此代码解码数据
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
decoder.dateDecodingStrategy = .secondsSince1970
let weatherInfo = try decoder.decode(CityWeatherInfo.self, from: data)
print(weatherInfo)
} catch {
print(error)
}