【问题标题】:How to decode a nested JSON struct with Swift Decodable?如何使用 Swift Decodable 解码嵌套的 JSON 结构?
【发布时间】:2021-08-07 06:06:09
【问题描述】:

这是我的 JSON

{
    "myItems": {
        "item1name": [{
            "url": "google.com",
            "isMobile": true,
            "webIdString": "572392"
        }, {
            "url": "hulu.com",
            "isMobile": false,
            "webIdString": "sad1228"
        }],
        "item2name": [{
            "url": "apple.com",
            "isMobile": true,
            "webIdString": "dsy38ds"
        }, {
            "url": "Facebook.com",
            "isMobile": true,
            "webIdString": "326dsigd1"
        }, {
            "url": "YouTube.com",
            "isMobile": true,
            "webIdString": "sd3dsg4k"
        }]
    }
}

json可以有多个item(比如item1name, item2name, item3name,...),每个item可以有多个object(例子中第一个item有2个object,第二个item有3个object)。

这是我想要保存到的结构(不完整):

struct ServerResponse: Decodable {
    let items: [MyItem]?
}

struct MyItem: Decodable {
    let itemName: String?
    let url: String?
    let isMobile: Bool?
    let webIdString: String?
}

在上面的例子中,这意味着items 列表应该有五个MyItem 对象。例如,这些将是 MyItem 对象:

#1: itemName: item1name, 网址:google.com, isMobile:是的, webIdString: 572392

#2: itemName: item1name, 网址:hulu.com, isMobile:假, webIdString: 悲伤1228

#3: itemName: item2name, 网址:apple.com, isMobile:是的, webIdString: dsy38ds

#4: itemName: item2name, 网址:Facebook.com, isMobile:是的, webIdString: 326dsigd1

#5: itemName: item2name, 网址:YouTube.com, isMobile:是的, webIdString: sd3dsg4k

使用 Decodable 对我来说最好的方法是什么?任何帮助,将不胜感激。我想这可能和这个问题类似:How to decode a nested JSON struct with Swift Decodable protocol?

【问题讨论】:

    标签: json swift nested decodable


    【解决方案1】:

    这是你所追求的结构:

    struct Websites: Decodable {
        let items: [Item]
    
        init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: Key.self)
            items = try container.decode([String: [Item]].self, forKey: .myItems).values.flatMap { $0 }
        }
    
        private enum Key: String, CodingKey {
            case myItems
        }
    }
    
    struct Item: Decodable {
        let url: String
        let isMobile: Bool
        let webIdString: String
    }
    

    【讨论】:

      【解决方案2】:

      使用以下代码根据您的要求解码嵌套的 JSON:

      import Foundation

      // MARK: - Websites
      struct Websites: Codable {
          var myItems: MyItems
      }
      
      // MARK: - MyItems
      struct MyItems: Codable {
          var item1Name, item2Name: [ItemName]
          enum CodingKeys: String, CodingKey {
              case item1Name = "item1name"
              case item2Name = "item2name"
          }
      }
      
      // MARK: - ItemName
      struct ItemName: Codable {
          var url: String
          var isMobile: Bool
          var webIDString: String
          enum CodingKeys: String, CodingKey {
              case url, isMobile
              case webIDString = "webIdString"
          }
      }
      

      注意:根据需要更改变量的名称。

      编辑

      如果您仍然遇到问题,请使用此应用将您的 JSON 转换为 Struct:

      Quick Type

      【讨论】:

      • 如果我不知道我会收到多少 itemNames,这是否有效?我可能只有item1Nameitem2Name。或者我可能有 5 个。或者我可能只有 1 个。这取决于服务器响应。
      • 如果item名称很多,则更新struct MyItems为 var itemName: [ItemName] enum CodingKeys: String, CodingKeys { case itemName }
      猜你喜欢
      • 2017-11-16
      • 2021-01-14
      • 1970-01-01
      • 1970-01-01
      • 2020-11-29
      • 2018-09-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-13
      相关资源
      最近更新 更多