【问题标题】:Dynamic key value type动态键值类型
【发布时间】:2025-12-24 08:00:12
【问题描述】:

我有一个使用 Codable 解码的 json。

struct Item: Codable {
    let data: Data // dictionary or array
}

struct Data: Codable {
    let id: Int
}

“数据”字段可以是数组或字典。

如何解码我的 json?

example json

【问题讨论】:

  • @Olympiloutre 你错了,这种格式其实很常见,Any可以避免。
  • @Sulthan 完全正确,我现在正在研究它。没有看到关联的“类型”,我认为它只是随机数据,可以是数组或字典。我的坏!
  • 在这两种情况下如何提取id?我假设字典很明显,但是数组呢?

标签: ios swift


【解决方案1】:

您必须根据type 解码data。这意味着您必须首先解码type,然后根据其值继续。 通常要存储此类项目,我们会使用带有关联值的enum

enum Item: Decodable {
    case onboarding(OnboardingData)
    case entry(EntryData)

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let type = try container.decode(String.self, forKey: .type)

        switch type {
        case "onboarding":
            let data = try container.decode(OnboardingData.self, forKey: .data)
            self = .onboarding(data)
        case "entry":
            let data = try container.decode(EntryData.self, forKey: .data)
            self = .entry(data)
        default:
            throw DecodingError.unknownType
        }
    }

    private enum CodingKeys: String, CodingKey {
        case type
        case data
    }

    private enum DecodingError: String, Error {
        case unknownType
    }
}

struct OnboardingData: Decodable {
}

struct EntryData: Decodable {
}

OnboardingDataEntryData 只是类型占位符。您可以将它们更改为任何想要的,例如一组项目。此外,您可以在其中包装数组。

【讨论】:

  • “类型”字段有很多值。不仅是“入职”和“入职”
  • 这个方案不适合这个json。由于类型字段的所有值都是未知的
  • @ИгорьСазонов 到底什么不合适?您是否只想解析您知道的值并跳过其他值?
  • 没有。我想解析所有的值。但我不知道“类型”字段的所有值。
  • @ИгорьСазонов type 字段是 JSON 格式的一部分。如果您不知道格式,则无法解析 JSON。