使用 Codable 解码具有不同类型属性的 json

问题描述

这就是我拥有的响应结构。

相同的 identifier 属性可以有一个与之关联的 data,它可以是其他对象的列表。 最外层的 table 是其他视图类型的列表,内部的 table 是行列表(如果有意义的话)。

{
  "identifier": "table","data": [
    {
      "identifier": "top_view","data": [
        {
          "value": "this is top header type view"
        }
      ]
    },{
      "identifier": "table","data": [
        {
          "value": "this is a first row in a table"
        },{
          "value": "this is a second row in a table"
        },{
          "value": "this is a third row in a table"
        }
      ]
    },{
      "identifier": "bottom_view","data": [
        {
          "value": "this is a footer type view"
        }
      ]
    }
  ]
}

我可以使用 swifts Codable 来解码吗?此类解码的解决方案通常涉及在不同的data 周围使用枚举,并使用它来注入与之关联的正确类型。但在本例中,identifier 是相同的。

如果我需要添加更多详细信息,请告诉我。

编辑 1 - 好吧,我正在尝试构建一个具有后端驱动 UI 的新应用程序。 这只是应用程序内屏幕的响应。要解释有关 json 的更多信息 - 最外面的表格是一个 tableview,可以有 3 个单元格 - 第一个是顶部标题,第二个是表格(同样有 3 个单元格,每个单元格都包含标签),第三个是引导页脚(不要与 tableviews 认页眉页脚混淆)。

我知道 json 本身可能有缺陷,但最初我希望它可以通过使用嵌套的 json 结构来工作(因此使用相同的 data 键) 在这种情况下,data 的值可以在不同的组件之间变化。

enter image description here

解决方法

我想我明白你想要达到的目标(从你对枚举的看法来看)。这是让你开始的东西-

struct TableableData: Codable {
    
    enum ViewType {
        
        case top(values: [String])
        case bottom(values: [String])
        case table(data: [TableableData])
        
        init?(identifier: String?,data: [TableableData]) {
            switch identifier {
            case "top_view": self = .top(values: data.compactMap{ $0.value })
            case "bottom_view": self = .top(values: data.compactMap{ $0.value })
            case "table": self = .table(data: data)
            default: return nil
            }
        }
    }
    
    let identifier: String?
    let value: String?
    let data: [TableableData]!
    
    var view: ViewType? {
        ViewType(identifier: identifier,data: data)
    }
}

我必须将所有字段都设为可选字段,以便针对您的 json 快速测试它,它确实有效。我建议使用解码器中的 init 将 optional 替换为空数组或其他东西。