Swift如何解码OpenSky API返回的无键JSON数组为Codable自定义模型
解决方法
报错原因
Swift 默认的 Codable 自动合成逻辑会期望 StateVector 对应的 JSON 结构是键值对字典,但 OpenSky 返回的 states 数组下每个元素都是按固定顺序排布的无键数组,因此需要手动实现 StateVector 的解码逻辑,按索引读取数组元素赋值给对应属性。
另外原代码存在两处类型不匹配问题需要修正:
icao24是6位十六进制字符串,并非UUID类型,需改为String- API 部分字段可能返回
null,对应属性需要声明为可选类型
修正后的完整代码
首先修改 StateVector 结构体,添加手动解码实现:
struct FlightState: Codable { let time: Int let states: [StateVector] struct StateVector: Codable { let icao24: String let callsign: String? let origin_country: String let time_position: Int? let last_contact: Int let longitude: Float? let latitude: Float? let baro_altitude: Float? let on_ground: Bool let velocity: Float? let true_track: Float? let vertical_rate: Float? let sensors: [Int]? let geo_altitude: Float? let squawk: String? let spi: Bool let position_source: Int init(from decoder: Decoder) throws { // 解码为无键数组容器,按顺序读取元素 var container = try decoder.unkeyedContainer() icao24 = try container.decode(String.self) // 呼号默认带尾部空格,这里加了trim处理,不需要可删除 callsign = try container.decodeIfPresent(String.self)?.trimmingCharacters(in: .whitespaces) origin_country = try container.decode(String.self) time_position = try container.decodeIfPresent(Int.self) last_contact = try container.decode(Int.self) longitude = try container.decodeIfPresent(Float.self) latitude = try container.decodeIfPresent(Float.self) baro_altitude = try container.decodeIfPresent(Float.self) on_ground = try container.decode(Bool.self) velocity = try container.decodeIfPresent(Float.self) true_track = try container.decodeIfPresent(Float.self) vertical_rate = try container.decodeIfPresent(Float.self) sensors = try container.decodeIfPresent([Int].self) geo_altitude = try container.decodeIfPresent(Float.self) squawk = try container.decodeIfPresent(String.self) spi = try container.decode(Bool.self) position_source = try container.decode(Int.self) } } }
原有的解码调用代码不需要修改即可正常运行:
let decoder = JSONDecoder() let flightState: FlightState = try! decoder.decode(FlightState.self, from: dataString.data(using: .utf8)!)
内容的提问来源于stack exchange,提问作者elementzero23
相关产品推荐
相关产品推荐

