在Swift 4中使用Decodable从嵌套JSON创建列表
解决Swift 4 Decodable解析包含数组的JSON键"list"的问题
嘿,这事儿其实没那么复杂,你只需要让结构体的层级和JSON的结构完全对应上就行!我来给你一步步拆解解决方案:
首先看你的JSON结构:顶层有cod、message、cnt几个字段,还有一个数组类型的list,数组里的每个元素又是包含dt、main、weather等字段的对象。所以我们需要定义两组核心结构体:
- 顶层的响应结构体,用来包裹所有顶层字段
- 对应
list数组元素的结构体,用来描述每个预报项的内容
完整的结构体定义
// 顶层响应结构体,对应整个JSON结构 struct WeatherResponse: Decodable { let cod: String let message: Double let cnt: Int let list: [WeatherForecastItem] // 直接定义为数组类型,对应JSON的"list"数组 } // 对应list数组里的单个元素 struct WeatherForecastItem: Decodable { let dt: Int let main: Main let weather: [Weather] let clouds: Clouds let wind: Wind let rain: Rain? // 部分字段可能非必填,用?标记为可选类型 let sys: Sys let dt_txt: String } // 以下是嵌套的子结构体,你可以根据实际JSON里的字段补充具体属性 struct Main: Decodable {} struct Weather: Decodable {} struct Clouds: Decodable {} struct Wind: Decodable {} struct Rain: Decodable {} struct Sys: Decodable {}
解析代码示例
拿到JSON数据后,用JSONDecoder正常解析即可,它会自动处理数组的解码逻辑:
do { let jsonData = yourRawJSONData // 替换成你的实际JSON数据 let response = try JSONDecoder().decode(WeatherResponse.self, from: jsonData) // 现在可以直接访问response.list,它是一个[WeatherForecastItem]类型的数组 for forecast in response.list { print("预报时间:\(forecast.dt_txt)") } } catch { print("解析失败:\(error.localizedDescription)") }
关键注意点
- 所有嵌套的子结构体都必须遵循
Decodable协议(Swift 4+中,只要结构体的所有属性都是Decodable类型,编译器会自动合成协议实现,不用手动写init(from decoder:)方法) - 如果JSON里某些字段可能不存在,一定要把结构体中对应的属性标记为可选类型(比如
rain: Rain?),避免因字段缺失导致解析失败 - 确保结构体的属性名和JSON的键名完全一致,如果有命名差异,可以通过
CodingKeys枚举来做映射
内容的提问来源于stack exchange,提问作者Brian Green
相关产品推荐
相关产品推荐

