【问题标题】:Parse using Codable in Swift在 Swift 中使用 Codable 进行解析
【发布时间】:2021-03-02 18:01:29
【问题描述】:

需要以这样一种方式解析此 JSON,以便我应该能够访问与“项目”节点中“启用”键内的每个计划相关的好处,如下所示:

让 items = Items[0].plans.main[0].enabled[0].text

{
  "MyData": {
    "data": {
      "benefits": {
        "B1": {
          "text": "Text1"
        },
        "B2": {
          "text": "Text2"
        },
        "B3": {
          "text": "text3"
        }
      }
    },
    "items": [
      {
        "plans": {
          "main": [
            {
              "name": "plan1",
              "enabled": [
                "B1",
                "B2"
              ],
              "disabled": [
                "B2",
                "B3"
              ]
            }
          ]
        }
      }
    ]
  }
}

我已经尝试如下实现,但似乎这不起作用

class Main: Codable {
    
    var name: String?
    
    var enabled: [String]?
    var disabled: [String]?
    
    enum CodingKeys: String, CodingKey {
        case name = "name"
        case enabled = "enabled"
        case disabled = "disabled"
    }

class MyData: Codable {
    var benefits: [String: Benefit]?
    
    enum CodingKeys: String, CodingKey {
        case benefits = "benefits"
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let propertyContainer = try container.nestedContainer(keyedBy: CustomDynamicKey.self, forKey: .benefits)
        self.benefits = propertyContainer.decodeValues()
    }

class Benefit: Codable {
    
    var text: String?
    
    enum CodingKeys: String, CodingKey {
        case text = "text"
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        
        text = try container.decode(String.self, forKey: .text)
    }
}

struct CustomDynamicKey: CodingKey {
    
    var stringValue: String

    init?(stringValue: String) {
        self.stringValue = stringValue
    }
    
    var intValue: Int? { return nil }
    
    init?(intValue: Int) { return nil }
    

extension KeyedDecodingContainer where Key == DynamicKey {
    
    func decodeValues() -> [String : Benefit] {
        var dict = [String : Benefit]()
        for key in allKeys {
            if let md = try? decode(Benefit.self, forKey: key) {
                dict[key.stringValue] = md
            } else {
                print("unsupported key")
            }
        }
        return dict
    }
}

我尝试单独解析模型。但是,我可以单独访问模型,但是在使用手动解析在所需的 init() 方法中解析 JSON 本身时,我需要将相应的好处与相应的计划进行映射。

【问题讨论】:

  • 我会将它们解析为[Sting: Benefit],在需要时为Plan 提供一些逻辑。我会将该属性设为private,并使用一个函数来根据计划检索允许的属性。即,制作更高级别的功能。

标签: json swift parsing nested codable


【解决方案1】:

一种方法是使用JSONDecoderJSONSerializationCodables 在这种情况下使用有点不舒服,您可以将 var benefits: [String: Benefit]? 设为可选(您已经拥有)并将其从 CodingKeys 枚举中删除。然后,使用JSONSerialization 填充benefits 字段。

This

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-22
    • 1970-01-01
    • 2020-07-28
    相关资源
    最近更新 更多