有人可以告诉我这是怎么回事吗?
它向我发送此错误:类型“ 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是这个:
{“坐标”:{“ lon”:-0.13,“纬度”:51.51},“天气”:[{“ id”:804,“主”:“云”,“描述”:“阴云” “,” icon“:” 04n“}],” base“:” stations“,” 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“:{”类型“:1,” id“:1414,”国家“:” GB“,”日出“:1592365362,”日落“:1592425222},”时区“:3600,” id “:2643743,” name“:” London“,” cod“:200}
答案 0 :(得分:0)
如果结构或类采用Codable
,则默认情况下将合成所需的方法init(from decoder: Decoder)
和encode(to encoder: Encoder)
。
但是,如果您自己实现一种方法,那么您也必须实现另一种方法。或者-在这种情况下-仅采用Decodable
,因为您仅在读取/解码数据。
您的代码中有一些不良做法。
自定义CodingKeys WeatherKeys
和MainKeys
是毫无意义的,因为在默认语法中,框架会生成名为CodingKeys
的密钥。自定义键仅在自定义实现中考虑。
nestedContainers
都不是必需的,并且如果它们由相同的CodingKeys进行键输入,则它们毫无意义。
如果字典键与结构成员名称匹配,则可以省略CodingKeys。
如果不打算修改struct成员的值,则将其声明为常量(let
)。
根据命名约定,变量应命名为 lowerCamelCased 。将 snake_case 转换为 camelCase 的便捷方法是指定convertFromSnakeCase
密钥解码策略。
openweathermap
API通过在URL中添加units=metric
来提供摄氏温度,或者通过添加units=imperial
来提供华氏温度。例如
https://api.openweathermap.org/data/2.5/weather?q=London&units=metric&appid=•••••••••••••"
通过指定Date
日期解码策略,可以将UNIX时间戳(1592362322)解码为secondsSince1970
可以以这种简单的形式创建结构
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)
}