简体   繁体   English

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

[英]Using Codable to decode json with attribute having different types

So this is the response structure that I have.这就是我的响应结构。

The same identifier attribute, can have a data associated with it that can be a list of other objects.同一个identifier属性,可以有一个与之关联的data ,可以是其他对象的列表。 The outermost table is list of other view types and the inner table is list of rows, if that makes sense.最外层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"
        }
      ]
    }
  ]
}

Can I use swifts Codable to decode this in anyway?无论如何,我可以使用 swifts Codable 来解码吗? Solutions for this type of decoding generally involve having an enum around different data and using this to inject the correct type associated with it.此类解码的解决方案通常涉及围绕不同data进行枚举,并使用它来注入与其关联的正确类型。 But in this case, the identifier is the same.但在这种情况下, identifier是相同的。

Let me know if I need to add in more details.让我知道是否需要添加更多详细信息。

Edit 1 - Well, I am trying to build a new app that has a backend driven UI.编辑 1 - 好吧,我正在尝试构建一个具有后端驱动 UI 的新应用程序。 This is just the response of a screen within the app.这只是应用程序内屏幕的响应。 To explain more about the json - The outermost table is a tableview that can have 3 cells - the first one being the top header, second a table(that again has 3 cells that each consists of label) and the third is a bootom footer (Not to be confused with a tableviews default header footer).要解释有关 json 的更多信息 - 最外面的表格是一个可以有 3 个单元格的表格视图 - 第一个是顶部 header,第二个是表格(同样有 3 个单元格,每个单元格都由标签组成),第三个是引导页脚(不要与 tableviews 默认的 header 页脚混淆)。

I understand that the json might be flawed in itself but initially I had hoped that it would work by employing a nested json structure (hence the use of same data key) The value of data in this case can change across different components.我知道 json 本身可能存在缺陷,但最初我希望它可以通过使用嵌套的 json 结构来工作(因此使用相同的data键)在这种情况下, data的值可以在不同的组件之间改变。

在此处输入图像描述

I think I understand what you are trying to achieve (from what you were saying about the enum).我想我了解您要实现的目标(根据您对枚举的说法)。 This is something to get you started --这是让你开始的东西——

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)
    }
}

I had to make all fields optional to quickly test it against your json, it works.我必须将所有字段设为可选,以便根据您的 json 快速测试它,它可以工作。 I would suggest using init from decoder to replace optional with empty array or something.我建议使用解码器中的 init 将 optional 替换为空数组或其他东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM