Swift中如何访问JSON内深度嵌套的WaznyDo字段数据
问题原因分析
- 第一层的
karty字段是动态字符串键值对,不是固定属性的结构体,不能直接写死属性名,未做对应处理会直接抛出键不存在的错误 - 日期字段
lastUpdate、WaznyDo用了非默认的格式,没有给Decoder指定特殊解码策略的话会直接抛出类型不匹配错误
完整解决方案代码
1. 数据模型定义
// 顶层数据模型 struct ResponseModel: Codable { let lastUpdate: Date let karty: [String: CardItem] // 动态卡号作为key } // karty对应的值模型 struct CardItem: Codable { let bilety: [BiletItem] } // bilety数组内的元素模型 struct BiletItem: Codable { let Taryfa: [String] let Strefa: String let WaznyDo: Date }
2. 解码逻辑实现
let decoder = JSONDecoder() // 自定义日期解码策略,适配两种不同的日期格式 decoder.dateDecodingStrategy = .custom { decoder in let container = try decoder.singleValueContainer() let dateStr = try container.decode(String.self) // 匹配WaznyDo的yyyy-MM-dd格式 let dateFormatter1 = DateFormatter() dateFormatter1.dateFormat = "yyyy-MM-dd" dateFormatter1.locale = Locale(identifier: "en_US_POSIX") if let date = dateFormatter1.date(from: dateStr) { return date } // 匹配lastUpdate的yyyy-MM-dd HH:mm:ss格式 let dateFormatter2 = DateFormatter() dateFormatter2.dateFormat = "yyyy-MM-dd HH:mm:ss" dateFormatter2.locale = Locale(identifier: "en_US_POSIX") if let date = dateFormatter2.date(from: dateStr) { return date } throw DecodingError.dataCorruptedError(in: container, debugDescription: "日期格式不匹配: \(dateStr)") } // 解码并取值示例 do { let result = try decoder.decode(ResponseModel.self, from: jsonData) // 遍历获取所有WaznyDo字段值 for (_, cardItem) in result.karty { for bilet in cardItem.bilety { let targetDate = bilet.WaznyDo // 此处可直接使用拿到的日期值 print("有效期至:\(targetDate)") } } } catch { print("解码错误:\(error)") }
关键注意点
- 如果不需要将日期字段转为Date类型,只想保留字符串值,直接把
lastUpdate和WaznyDo的类型声明为String即可,不需要配置自定义日期解码策略也能正常解码 - 动态键的
karty必须声明为[String: CardItem]类型,不要写为固定属性的结构体,否则会直接解码失败
内容的提问来源于stack exchange,提问作者Jakub Bąk
相关产品推荐
相关产品推荐

