当您不知道 Swift 中的项目类型时,如何解码嵌套的 JSON 数据? [复制]

Posted

技术标签:

【中文标题】当您不知道 Swift 中的项目类型时,如何解码嵌套的 JSON 数据? [复制]【英文标题】:How to decode nested JSON data when you don't know which type of the item would be in Swift? [duplicate] 【发布时间】:2022-01-03 19:16:02 【问题描述】:

我正在尝试从 API 调用解码 JSON 数据,并有一些可解码的类来解码 JSON,但我遇到了一个问题。 在 JSON 中,有一个项目具有相同的名称(比如说“值”),但字符串或 int 取决于它的“类型”。

有人可以帮我在这种情况下如何构建我的可解码类吗? (我的示例可解码类如下)

class ExampleClassToDecode: Decodable 
    let type: String
    let value: String? // this item can be either String or Int in the callback JSON data

示例 JSON

0:
"type":"type1"
"value":"73%"

1:
"type":"type2"
"value":2

2:
"type":"type3"
"value":NULL

【问题讨论】:

【参考方案1】:

您可以使用带有关联值的枚举。

可编码的一致性:

struct Example: Codable 
    let type: String
    let value: Value?

enum Value: Codable 
    case string(String)
    case int(Int)

    init(from decoder: Decoder) throws 
        let container = try decoder.singleValueContainer()

        if let string = try? container.decode(String.self) 
            self = .string(string)
            return
        
        if let int = try? container.decode(Int.self) 
            self = .int(int)
            return
        

        throw CodableError.failedToDecodeValue
    

    func encode(to encoder: Encoder) throws 
        var container = encoder.singleValueContainer()

        switch self 
        case .string(let string): try container.encode(string)
        case .int(let int): try container.encode(int)
        
    

enum CodableError: Error 
    case failedToDecodeValue

用法:

let json1 = """

    "type": "type1",
    "value": "73%"

"""

let json2 = """

    "type": "type2",
    "value": 2

"""

let json3 = """

    "type": "type3",
    "value": null

"""
do 
    let data = Data(json1.utf8) // <- Swap this for other JSONs
    let result = try JSONDecoder().decode(Example.self, from: data)
    print(result)

    switch result.value 
    case .string(let string): print("percentage: \(string)")
    case .int(let int): print("counter: \(int)")
    case nil: print("no value")
    
 catch 
    print(error)

【讨论】:

【参考方案2】:

我会将其保留为 String 在您的可解码模型类和您的视图控制器中,我将使用 type 来了解如何转换 value。 如果是type1,那么我就会知道该值为String。 如果是type2,那么我知道这是一个Int,所以我将String 转换为Int。

编辑:George 示例是一个更好的主意,因为它是在 Model 类中进行转换,因此您以后无需在 ViewController 中担心。

【讨论】:

以上是关于当您不知道 Swift 中的项目类型时,如何解码嵌套的 JSON 数据? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

当您不知道内容的大小时,如何在 react native 中为高度设置动画?

当您不知道页数时,如何使用 Node.js 在 while 循环中向 API 发出多个分页 GET 请求?

当您不知道键的名称时访问对象内部的数据

Angular 2:当您不知道 childComponent 的类时,如何将 childComponent 属性发送给 parent?

当您不记得约束名称时如何删除约束[重复]

使用基类指针查找派生类对象的大小