Learn Courses My Dashboard

How to parse this json dictionary

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?

You should watch this video! Parsing JSON always works the same way no matter the format of the JSON and your model