【问题标题】:Using Codable to decode json with attribute having different types使用 Codable 解码具有不同类型属性的 json
【发布时间】:2021-03-29 00:52:31
【问题描述】:

这就是我的响应结构。

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

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

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

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

【问题讨论】:

  • 如果可能的话,首先让你改变 json,这样做。它的设计很差,不应该为同一个键有不同的数据类型。如果无法更改,则需要实现自己的init(decoder) 方法
  • 你想把它解码成什么模型?
  • 这绝对是可以解码的,但它会有助于显示你想要结束的 Swift 结构。如果你打算纯粹通过编写 Swift 代码(没有任何 JSON)来对上述数据结构进行编码,你最希望它看起来像什么?这个 JSON 代表什么还不是很清楚。

标签: ios swift swift5 codable decodable


【解决方案1】:

我想我理解你想要达到的目标(从你所说的枚举中)。这是让你开始的东西--

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 替换为空数组或其他东西。

【讨论】:

    猜你喜欢
    • 2021-03-25
    • 2018-06-05
    • 2021-10-15
    • 2018-11-04
    • 2023-04-04
    • 2020-04-28
    • 2020-04-01
    • 2018-11-10
    相关资源
    最近更新 更多