在 Swift 中解析嵌套的 JSON 数组

施瓦茨

我很难弄清楚如何在 Swift 中解析 JSON。我想从这个 xml 中解析出 RouteKey 和 routeNAME。我尝试了一些不同的教程,并尝试使用 quicktype,但我无法让它工作。

{
"response": {
    "data": [{
        "fieldData": {
            "RouteKey": "AIwACAAAAB4AAABcAAAAmQAAAKYAAAB42mNYxsDOZMfAwMCyjIFhHSMDwy8g24SDgYGJCchg6I39 MjFlkOdAQr2VBQICTFU2jD8\/w8R LCfAQlwAXHqlS5OJoaXd249WvXjtxpMZtuOfCFmhkorPBq5996vADqACS6odOH0dpDNigIMHgwA UQgxkMEKTE=",
            "Route ID": 3.5375656527008e+56,
            "userID": "1",
            "routeNAME": "Zoo to Hartley",
            "Job ID": "",
            "RouteXML": "",
            "length": "",
            "width": "",
            "weight": "",
            "height": "",
            "numtrailers": "",
            "truckID": "1"
        },
        "portalData": [],
        "recordId": "14",
        "modId": "1"
    }, {
        "fieldData": {
            "RouteKey": "ADYBCAAAAB4AAABcAAAAmQAAAJsBAAB42n1QPUtDMRQ9SSMNtmj6dCi6BIVHnbS4KkR4Q10F97e5Kbi5RXmV2lUXcSn0P2g3K3QouIjg1kUnR0EnEetNXipOHrhJ7uc5ubhiRQ6CP 6f7eNsZFYQ0Pk4jw750QbG4zzwdos\/mCa7rC99c2y j16eFr7iSeamdxBp\/Nv4IEbrLPB6DPY r3cksLpM0XR xsUE czXhDqpwU1X9fcBTa7iYClaIiTJrHtUXeCMWxjX2FeIOVHRJLPdtAyiAYXkDqhAppiTUxwl4WdU5W6BJqyJVh2d41OzGNcudLuGyskWQ2aSpPRaJI62wJB oQXx2wxoOHmmQHqIXzvRQNlv1bD8hnAfUE4DgspuLniyfFv 3YQln9lmhh NMTn3hVV0jw==",
            "Route ID": 2.7005919429558e+57,
            "userID": "1",
            "routeNAME": "Perth to Hartley",
            "Job ID": "",
            "RouteXML": "",
            "length": "",
            "width": "",
            "weight": "",
            "height": "",
            "numtrailers": "",
            "truckID": "1"
        },
        "portalData": [],
        "recordId": "19",
        "modId": "1"
    }]
},
"messages": [{
    "code": "0",
    "message": "OK"
}]

}

这是我到目前为止检索 JSON 的代码:

let url = URL(string: "https://....")
URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) -> Void in
if let jsonObj = try? JSONSerialization.jsonObject(with: data!) as? NSDictionary {
print(jsonObj!.value(forKey: "response")!)
}
}).resume()
达美什·赫尼

如果你不想让它与Codable 这里一起工作,这是你的文件。

它看起来像:

struct Root: Codable {
    let response: Response
    let messages: [Message]
}

struct Message: Codable {
    let code, message: String
}

struct Response: Codable {
    let data: [Datum]
}

struct Datum: Codable {
    let fieldData: FieldData
    let portalData: [JSONAny]
    let recordID, modID: String

    enum CodingKeys: String, CodingKey {
        case fieldData, portalData
        case recordID = "recordId"
        case modID = "modId"
    }
}

struct FieldData: Codable {
    let routeKey: String
    let routeID: Double
    let userID, routeNAME, jobID, routeXML: String
    let length, width, weight, height: String
    let numtrailers, truckID: String

    enum CodingKeys: String, CodingKey {
        case routeKey = "RouteKey"
        case routeID = "Route ID"
        case userID, routeNAME
        case jobID = "Job ID"
        case routeXML = "RouteXML"
        case length, width, weight, height, numtrailers, truckID
    }
}

// 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)
        }
    }
}

然后你可以解码JSON

let root = try? JSONDecoder().decode(Root.self, from: jsonData!)

如果你想data从你的root对象访问密钥,你可以用

root?.response.data

这是Array类型的An[Datum]?

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

Swift - 嵌套 JSON 对象中的解析数组不起作用

来自分类Dev

在Swift中解析JSON数组

来自分类Dev

在Java中解析嵌套的json数组

来自分类Dev

在android中解析json嵌套数组

来自分类Dev

Swift JSON 解析访问数组

来自分类Dev

使用数组根对象在Swift中解析JSON数组

来自分类Dev

将JSON数组解析为Swift数组

来自分类Dev

尝试在Swift上解析JSON数组数组

来自分类Dev

将Json数组中的对象解析为字典Swift

来自分类Dev

如何在Swift中解析具有对象的JSON数组

来自分类Dev

将 Swift 中的 JSON 解析为类数组

来自分类Dev

Dart - 解析嵌套的 Json 数组

来自分类Dev

如何在Android中解析嵌套的JSON数组

来自分类Dev

以特定方式解析Excel中的JSON嵌套数组

来自分类Dev

如何在Android中解析嵌套的JSON数组

来自分类Dev

使用Angular.js解析JSON中的嵌套对象数组

来自分类Dev

如何使用 JavaScript 解析嵌套数组中的 JSON 值

来自分类Dev

如何在 Flutter 中解析嵌套的 JSON 数组?

来自分类Dev

解析嵌套的 JSON SWIFT 4

来自分类Dev

解析多维JSON数组,嵌套数组

来自分类Dev

解析json字典,数组中的数组?获取更深层嵌套中的关键对象?

来自分类Dev

在Swift中从JSON数组获取值

来自分类Dev

在Swift中解码基于数组的JSON

来自分类Dev

在Swift 5中更新JSON数组

来自分类Dev

在Swift中解码基于数组的JSON

来自分类Dev

在Swift中从JSON数组获取值

来自分类Dev

在 Swift 中循环嵌入 JSON 数组?

来自分类Dev

Swift:从 JSON 编码的数据中获取数组

来自分类Dev

在Swift中解析Json