简体   繁体   English

使用 Swift Decodable 解码具有动态键值的 JSON,键值名称在 JSON 模型中的其他地方找到

[英]Decoding JSON that has a dynamic key value with the key value name found elsewhere in JSON model using Swift Decodable

When I make an API request, I get returned a JSON structure that contains several objects which all have unique key value names.当我发出 API 请求时,我得到一个 JSON 结构,其中包含多个对象,这些对象都具有唯一的键值名称。 Therefore I cannot use the regular Decodable protocol to break down the JSON into different instances.因此我不能使用常规的 Decodable 协议将 JSON 分解为不同的实例。 However, these key value names are found elsewhere in my JSON structure under known constant values that I can access normally.但是,这些键值名称可以在我可以正常访问的已知常量值下的 JSON 结构中的其他地方找到。 Here is some example code I created to demonstrate my issue:这是我创建的一些示例代码来演示我的问题:

let jsonString = """
{
    "uniqueObjects": {
        "uniqueObject:1132435": {
            "firstName": "John"
            "lastName": "Smith"
        }
        "uniqueObject2:119672": {
            "firstName": "Jane"
            "lastName": "Doe"
        }
        "uniqueObject3:008997": {
            "firstName": "Sam"
            "lastName": "Greenfield"
        }
    }
    "keys": {
        "object1": {
            "key": "uniqueObject1:132435"
        }
        "object2": {
            "key": "uniqueObject2:119672"
        }
        "object3": {
            "key": "uniqueObject3:008997"
        }
}
"""

let jsonData = Data(jsonString.utf8)

let decodedData = try? JSONDecoder().decode(JSONData.self, from: jsonData)

print(decodedData?.uniqueObjects.firstObject.firstName ?? "No data decoded")

struct JSONData: Decodable {
    let uniqueObjects: Object
    let keys: KeyObjects
}

struct Object: Decodable {
    let firstObject: Names
    let secondObject: Names
    let thirdObject: Names
    
    private enum DynamicCodingKeys: String, CodingKey {
        case firstObject = "???" // this needs to be mapped to the unique value for object 1
        case secondObject = "??" // this needs to be mapped to the unique value for object 2
        case thirdObject = "????" // etc.
        // I don't think this works because Xcode says that the strings must be raw literals
    }
}

struct KeyObjects: Decodable {
    let object1: Key
    let object2: Key
    let object3: Key
}

struct Key: Decodable {
    let key: String
}

struct Names: Decodable {
    let firstName: String
    let lastName: String
}

The approach I took here, which is definitely wrong, was to create a coding key for each of the unique objects and map its name to a String that would be somehow be decoded from its relative key value pair in the key object.我在这里采用的方法,这绝对是错误的,是为每个唯一对象创建一个编码键,并将其名称映射到一个字符串,该字符串将以某种方式从键对象中的相对键值对中解码。 CodingKeys, at least what I have tried, do not allow you to do this so I need a new method in order to access this code. CodingKeys,至少我已经尝试过,不允许您这样做,因此我需要一种新方法来访问此代码。 I also need to know how I can reference the data once I decode it (just printing it out for now).我还需要知道如何在解码后引用数据(现在只是打印出来)。 Help and a short explanation would be much appreciated as I am a beginner developer.由于我是初学者开发人员,因此非常感谢帮助和简短的解释。 Thanks!谢谢!

Unless I have misunderstood it looks to me like you are over complicating things.除非我误解了,否则在我看来,您似乎把事情复杂化了。 This is how I would define the types for decoding the json这就是我定义用于解码 json 的类型的方式

struct Response: Codable {
    let uniqueObjects: [String: User]
    let keys: [String: ObjectKey]
}

struct ObjectKey: Codable {
    let key: String
}

struct User: Codable {
    let firstName: String
    let lastName: String
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM