将 Codeable 用于字典

Use Codeable for dictionary

我正在尝试将 Codeable 用于 API

的以下响应
{
    "id": "1",
    "name": "Demo 1",
    "description": "Description 1",
    "created": "2020-04-12T17:20:32.687628Z",
    "creator": {
        "id": 10,
        "name": "My User",
        "image": null
    },
    "images": [],
    "allergens": []
}

这是我的代码

struct MyObject: Codable {
        let id: Int
        let name, description, created: String
        let images, allergens: [String]
        let creator: [String: Any]?
    }

我希望我的示例 API 对象具有 Codable 结构。我在主对象中有另一个对象。如何使用 struct 和 Codable 解决 Swift 中的这个问题?

可能是这样的:

struct MyObject: Codable {
    let id, name, description, created: String
    let creator: Creator
    let images, allergens: [JSONAny] //Choose perfect type

}

struct Creator: Codable {
    let id: Int
    let name: String
    let image: String
}

您可以像这样为 Creator 或自定义解码器创建结构:

struct MyObject: Decodable {
    let id: String
    let name, description, created: String
    let images, allergens: [String]
    let creatorId: Int
    let creatorName: String

    enum CodingKeys: String, CodingKey {
        case id, name, description, created, images, allergens, creator
    }

    enum CreatorKeys: String, CodingKey {
        case creatorId = "id"
        case creatorName = "name"
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        id = try values.decode(String.self, forKey: .id)
        name = try values.decode(String.self, forKey: .name)
        description = try values.decode(String.self, forKey: .description)
        created = try values.decode(String.self, forKey: .created)
        images = try values.decode([String].self, forKey: .images)
        allergens = try values.decode([String].self, forKey: .allergens)

        let creatorContainer = try values.nestedContainer(keyedBy: CreatorKeys.self, forKey: .creator)

        creatorId = try creatorContainer.decode(Int.self, forKey: .creatorId)
        creatorName = try creatorContainer.decode(String.self, forKey: .creatorName)
    }
}

let decodedJSon = try JSONDecoder().decode(MyObject.self, from: json.data(using: .utf8)!)