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

Ios 使用Codable解码具有不同类型属性的json,ios,swift,swift5,codable,decodable,Ios,Swift,Swift5,Codable,Decodable,这就是我的反应结构 相同的标识符属性可以具有与其关联的数据,该数据可以是其他对象的列表。 最外面的表是其他视图类型的列表,而最里面的表是行列表(如果有意义的话) { "identifier": "table", "data": [ { "identifier": "top_view", "data": [ {

这就是我的反应结构

相同的
标识符
属性可以具有与其关联的
数据
,该数据可以是其他对象的列表。 最外面的
是其他视图类型的列表,而最里面的
是行列表(如果有意义的话)

{
  "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来解码吗?这类解码的解决方案通常涉及在不同的
数据
周围有一个枚举,并使用它注入与之关联的正确类型。但是在这种情况下,
标识符
是相同的

如果我需要补充更多细节,请告诉我

编辑1- 嗯,我正在尝试建立一个新的应用程序,它有一个后端驱动的用户界面。 这只是应用程序内屏幕的响应。
为了进一步解释json,最外层的表是一个可以有3个单元格的tableview,第一个是顶部页眉,第二个是表(同样有3个单元格,每个单元格由标签组成),第三个是bootom页脚(不要与tableview默认的页脚混淆)

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


我想我理解了您试图实现的目标(从您对enum的看法中)。这是让你开始的事情--


我必须使所有字段都是可选的,以便根据您的json快速测试它,它可以工作。我建议使用解码器中的init来替换可选的空数组或其他东西。

我想我理解您试图实现的目标(从您对enum的描述中)。这是让你开始的事情--


我必须使所有字段都是可选的,以便根据您的json快速测试它,它可以工作。我建议使用解码器中的init来替换可选的空数组或其他内容。

如果可能,请先更改json。它的设计很差,同一个键不应该有不同的数据类型。如果你不能改变它,那么你需要实现你自己的方法,你想把它解码成什么样的模型?这当然是可以解码的,但这将有助于展示你想以什么样的Swift结构结束。如果您打算纯粹通过编写Swift代码(没有任何JSON)对上述数据结构进行编码,您最希望它是什么样子?这个JSON代表什么还不是很清楚。首先,如果可能的话,请更改JSON。它的设计很差,同一个键不应该有不同的数据类型。如果你不能改变它,那么你需要实现你自己的方法,你想把它解码成什么样的模型?这当然是可以解码的,但这将有助于展示你想以什么样的Swift结构结束。如果您打算纯粹通过编写Swift代码(没有任何JSON)对上述数据结构进行编码,您最希望它是什么样子?这个JSON代表什么还不是很清楚。
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)
    }
}