Hey y’all, sorry to bother you guys, but again, I have a question on how to parse dictionaries in swift UI. I have my json file right here:
{"request":{"lang":"en","currency":"USD","time":7,"id":"7olnfh9mnp4","server":"g","host":"airlabs.co","pid":6450,"key":{"id":17168,"api_key":"7c626913-9abc-4599-97e7-0be4c8778647","type":"free","trial_price":null,"expired":null,"registered":"2021-07-26T16:47:23.000Z","limits_by_hour":2500,"limits_by_minute":250,"limits_by_month":1000,"limits_total":948,"demo_methods":[],"usage_by_hour":21,"usage_by_minute":2},"params":{"flight_iata":"CI59","lang":"en"},"version":9,"method":"flights","client":{"ip":"68.93.138.14","geo":{"country_code":"US","country":"United States","continent":"North America","lat":38,"lng":-97},"connection":{"type":"cable/dsl","isp_code":7018,"isp_name":"AT&T Services, Inc."},"device":{},"agent":{},"karma":{"is_blocked":false,"is_crawler":false,"is_bot":false,"is_friend":false,"is_regular":true}}},"response":[{"hex":"899125","flag":"TW","lat":3.5,"lng":144.45,"dir":147,"dep_iata":"TPE","arr_iata":"AKL","aircraft_icao":"A359","flight_iata":"CI59","flight_number":"59","airline_iata":"CI","alt":12500,"speed":874,"v_speed":0,"squawk":"0000","status":"en-route"}],"terms":"Unauthorized access is prohibited and punishable by law. \nReselling data 'As Is' without AirLabs.Co permission is strictly prohibited. \nFull terms on https://airlabs.co/. \nContact us info@airlabs.co"}
And my model right here:
// This file was generated from JSON Schema using quicktype, do not modify it directly.
// To parse the JSON, add this file to your project and do:
//
// let flightModel = try? newJSONDecoder().decode(FlightModel.self, from: jsonData)
import Foundation
// MARK: - FlightModel
struct FlightModel: Codable {
let request: Request
let response: [Response]
let terms: String
}
// MARK: - Request
struct Request: Codable {
let lang, currency: String
let time: Int
let id, server, host: String
let pid: Int
let key: Key
let params: Params
let version: Int
let method: String
let client: Client
}
// MARK: - Client
struct Client: Codable {
let ip: String
let geo: Geo
let connection: Connection
let device, agent: Agent
let karma: Karma
}
// MARK: - Agent
struct Agent: Codable {
}
// MARK: - Connection
struct Connection: Codable {
let type: String
let ispCode: Int
let ispName: String
enum CodingKeys: String, CodingKey {
case type
case ispCode = "isp_code"
case ispName = "isp_name"
}
}
// MARK: - Geo
struct Geo: Codable {
let countryCode, country, continent: String
let lat, lng: Int
enum CodingKeys: String, CodingKey {
case countryCode = "country_code"
case country, continent, lat, lng
}
}
// MARK: - Karma
struct Karma: Codable {
let isBlocked, isCrawler, isBot, isFriend: Bool
let isRegular: Bool
enum CodingKeys: String, CodingKey {
case isBlocked = "is_blocked"
case isCrawler = "is_crawler"
case isBot = "is_bot"
case isFriend = "is_friend"
case isRegular = "is_regular"
}
}
// MARK: - Key
struct Key: Codable {
let id: Int
let apiKey, type: String
let trialPrice, expired: JSONNull?
let registered: String
let limitsByHour, limitsByMinute, limitsByMonth, limitsTotal: Int
let demoMethods: [JSONAny]
let usageByHour, usageByMinute: Int
enum CodingKeys: String, CodingKey {
case id
case apiKey = "api_key"
case type
case trialPrice = "trial_price"
case expired, registered
case limitsByHour = "limits_by_hour"
case limitsByMinute = "limits_by_minute"
case limitsByMonth = "limits_by_month"
case limitsTotal = "limits_total"
case demoMethods = "demo_methods"
case usageByHour = "usage_by_hour"
case usageByMinute = "usage_by_minute"
}
}
// MARK: - Params
struct Params: Codable {
let flightIata, lang: String
enum CodingKeys: String, CodingKey {
case flightIata = "flight_iata"
case lang
}
}
// MARK: - Response
struct Response: Codable {
let hex, flag: String
let lat, lng: Double
let dir: Int
let depIata, arrIata, aircraftIcao, flightIata: String
let flightNumber, airlineIata: String
let alt, speed, vSpeed: Int
let squawk, status: String
enum CodingKeys: String, CodingKey {
case hex, flag, lat, lng, dir
case depIata = "dep_iata"
case arrIata = "arr_iata"
case aircraftIcao = "aircraft_icao"
case flightIata = "flight_iata"
case flightNumber = "flight_number"
case airlineIata = "airline_iata"
case alt, speed
case vSpeed = "v_speed"
case squawk, status
}
}
// MARK: - Encode/decode helpers
class JSONNull: Codable, Hashable {
public static func == (lhs: JSONNull, rhs: JSONNull) -> Bool {
return true
}
public var hashValue: Int {
return 0
}
public init() {}
public required init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if !container.decodeNil() {
throw DecodingError.typeMismatch(JSONNull.self, DecodingError.Context(codingPath: decoder.codingPath, debugDescription: "Wrong type for JSONNull"))
}
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encodeNil()
}
}
class JSONCodingKey: CodingKey {
let key: String
required init?(intValue: Int) {
return nil
}
required init?(stringValue: String) {
key = stringValue
}
var intValue: Int? {
return nil
}
var stringValue: String {
return key
}
}
class JSONAny: Codable {
let value: Any
static func decodingError(forCodingPath codingPath: [CodingKey]) -> DecodingError {
let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Cannot decode JSONAny")
return DecodingError.typeMismatch(JSONAny.self, context)
}
static func encodingError(forValue value: Any, codingPath: [CodingKey]) -> EncodingError {
let context = EncodingError.Context(codingPath: codingPath, debugDescription: "Cannot encode JSONAny")
return EncodingError.invalidValue(value, context)
}
static func decode(from container: SingleValueDecodingContainer) throws -> Any {
if let value = try? container.decode(Bool.self) {
return value
}
if let value = try? container.decode(Int64.self) {
return value
}
if let value = try? container.decode(Double.self) {
return value
}
if let value = try? container.decode(String.self) {
return value
}
if container.decodeNil() {
return JSONNull()
}
throw decodingError(forCodingPath: container.codingPath)
}
static func decode(from container: inout UnkeyedDecodingContainer) throws -> Any {
if let value = try? container.decode(Bool.self) {
return value
}
if let value = try? container.decode(Int64.self) {
return value
}
if let value = try? container.decode(Double.self) {
return value
}
if let value = try? container.decode(String.self) {
return value
}
if let value = try? container.decodeNil() {
if value {
return JSONNull()
}
}
if var container = try? container.nestedUnkeyedContainer() {
return try decodeArray(from: &container)
}
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self) {
return try decodeDictionary(from: &container)
}
throw decodingError(forCodingPath: container.codingPath)
}
static func decode(from container: inout KeyedDecodingContainer<JSONCodingKey>, forKey key: JSONCodingKey) throws -> Any {
if let value = try? container.decode(Bool.self, forKey: key) {
return value
}
if let value = try? container.decode(Int64.self, forKey: key) {
return value
}
if let value = try? container.decode(Double.self, forKey: key) {
return value
}
if let value = try? container.decode(String.self, forKey: key) {
return value
}
if let value = try? container.decodeNil(forKey: key) {
if value {
return JSONNull()
}
}
if var container = try? container.nestedUnkeyedContainer(forKey: key) {
return try decodeArray(from: &container)
}
if var container = try? container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key) {
return try decodeDictionary(from: &container)
}
throw decodingError(forCodingPath: container.codingPath)
}
static func decodeArray(from container: inout UnkeyedDecodingContainer) throws -> [Any] {
var arr: [Any] = []
while !container.isAtEnd {
let value = try decode(from: &container)
arr.append(value)
}
return arr
}
static func decodeDictionary(from container: inout KeyedDecodingContainer<JSONCodingKey>) throws -> [String: Any] {
var dict = [String: Any]()
for key in container.allKeys {
let value = try decode(from: &container, forKey: key)
dict[key.stringValue] = value
}
return dict
}
static func encode(to container: inout UnkeyedEncodingContainer, array: [Any]) throws {
for value in array {
if let value = value as? Bool {
try container.encode(value)
} else if let value = value as? Int64 {
try container.encode(value)
} else if let value = value as? Double {
try container.encode(value)
} else if let value = value as? String {
try container.encode(value)
} else if value is JSONNull {
try container.encodeNil()
} else if let value = value as? [Any] {
var container = container.nestedUnkeyedContainer()
try encode(to: &container, array: value)
} else if let value = value as? [String: Any] {
var container = container.nestedContainer(keyedBy: JSONCodingKey.self)
try encode(to: &container, dictionary: value)
} else {
throw encodingError(forValue: value, codingPath: container.codingPath)
}
}
}
static func encode(to container: inout KeyedEncodingContainer<JSONCodingKey>, dictionary: [String: Any]) throws {
for (key, value) in dictionary {
let key = JSONCodingKey(stringValue: key)!
if let value = value as? Bool {
try container.encode(value, forKey: key)
} else if let value = value as? Int64 {
try container.encode(value, forKey: key)
} else if let value = value as? Double {
try container.encode(value, forKey: key)
} else if let value = value as? String {
try container.encode(value, forKey: key)
} else if value is JSONNull {
try container.encodeNil(forKey: key)
} else if let value = value as? [Any] {
var container = container.nestedUnkeyedContainer(forKey: key)
try encode(to: &container, array: value)
} else if let value = value as? [String: Any] {
var container = container.nestedContainer(keyedBy: JSONCodingKey.self, forKey: key)
try encode(to: &container, dictionary: value)
} else {
throw encodingError(forValue: value, codingPath: container.codingPath)
}
}
}
static func encode(to container: inout SingleValueEncodingContainer, value: Any) throws {
if let value = value as? Bool {
try container.encode(value)
} else if let value = value as? Int64 {
try container.encode(value)
} else if let value = value as? Double {
try container.encode(value)
} else if let value = value as? String {
try container.encode(value)
} else if value is JSONNull {
try container.encodeNil()
} else {
throw encodingError(forValue: value, codingPath: container.codingPath)
}
}
public required init(from decoder: Decoder) throws {
if var arrayContainer = try? decoder.unkeyedContainer() {
self.value = try JSONAny.decodeArray(from: &arrayContainer)
} else if var container = try? decoder.container(keyedBy: JSONCodingKey.self) {
self.value = try JSONAny.decodeDictionary(from: &container)
} else {
let container = try decoder.singleValueContainer()
self.value = try JSONAny.decode(from: container)
}
}
public func encode(to encoder: Encoder) throws {
if let arr = self.value as? [Any] {
var container = encoder.unkeyedContainer()
try JSONAny.encode(to: &container, array: arr)
} else if let dict = self.value as? [String: Any] {
var container = encoder.container(keyedBy: JSONCodingKey.self)
try JSONAny.encode(to: &container, dictionary: dict)
} else {
var container = encoder.singleValueContainer()
try JSONAny.encode(to: &container, value: self.value)
}
}
}
How can I decode this json with this model?