如何快速反序列化 JSON

Posted

技术标签:

【中文标题】如何快速反序列化 JSON【英文标题】:How to deserialize JSON in swift 【发布时间】:2019-10-05 18:00:46 【问题描述】:

我想将 JSON 文件解码为模型对象。不幸的是,它不能以正确的方式工作。所以我没有收到错误,但“解码结果”不符合我的期望。 我有以下 JSON 文件,我想在显示的结构中对其进行解码。我已经修剪了 json 文件。为什么只给我一个“滑块图像”而不是 5(ImageSlider 的属性图像包含一个只有第一个图像/元素的数组)。 我错过了什么?

JSON:

["imageSlider" : [
        "image" : [
             "imageId" : "1",
             "imageName" : "germany1",
             "imageBigName" : "germany1_BIG",
             "imageRights" : "Peter"
        ],
        "image" : [
             "imageId" : "2",
             "imageName" : "germany2",
             "imageBigName" : "germany2_BIG",
             "imageRights" : "Peter"
        ],
        "image" : [
             "imageId" : "3",
             "imageName" : "germany3",
             "imageBigName" : "germany3_BIG",
             "imageRights" : "Peter"
        ],
        "image" : [
             "imageId" : "4",
             "imageName" : "germany4",
             "imageBigName" : "germany4_BIG",
             "imageRights" : "Peter"
        ],
        "image" : [
             "imageId" : "5",
             "imageName" : "germany5",
             "imageBigName" : "germany5_BIG",
             "imageRights" : "Peter"
        ]
    ]
]

斯威夫特:

struct CountryModel : Decodable, Equatable     
    var countryName : String
    var inhabitants : String
    var capital : String
    var currency : String
    var imageName : String
    var imageSlider: [ImagesSlider]


struct ImagesSlider : Decodable, Equatable 
    var image: [Image]


struct Image : Decodable, Equatable 
    var imageId: String
    var imageName: String
    var imageBigName: String
    var imageRights: String

解码:

func loadData() -> [CountryModel] 
    var data: Data

    guard let file = Bundle.main.url(forResource: "data", withExtension: "json") else 
        fatalError("Error")
    

    data = try! Data(contentsOf: file)
    let decoder = JSONDecoder()
    return try! decoder.decode([CountryModel].self, from: data)


感谢您的帮助...

编辑: 链接的问题没有解决我的问题...

【问题讨论】:

Simple and clean way to convert JSON string to Object in Swift的可能重复 【参考方案1】:

json 看起来不对,记住每个 json 对象应该只有一个唯一键。现在是:

[
  
    "imageSlider": [
      
        "image": [
          
            "imageId": "1",
            "imageName": "germany1",
            "imageBigName": "germany1_BIG",
            "imageRights": "Peter"
          
        ],
        "image": [
          
            "imageId": "2",
            "imageName": "germany2",
            "imageBigName": "germany2_BIG",
            "imageRights": "Peter"
          
        ]
      
    ]
  
]

应该是这样的:

[
    
      "imageSlider": [
        
          "image": [
            
              "imageId": "1",
              "imageName": "germany1",
              "imageBigName": "germany1_BIG",
              "imageRights": "Peter"
            ,
            
              "imageId": "2",
              "imageName": "germany2",
              "imageBigName": "germany2_BIG",
              "imageRights": "Peter"
            
          ]
        
      ]
    
  ]

请注意,“germany2”项目位于图像数组中。

let decoder = JSONDecoder()
let jsonData = Data(jsonString.utf8)
do 
  let country = try decoder.decode([CountryModel].self, from: jsonData)
  print(country[0].imageSlider[0].image.count)
 catch 
  print(error.localizedDescription)


// Console message
2

【讨论】:

【参考方案2】:

因为您的 JSON 包含多个 Images 对象具有相同的键!这是无效的,并且每个都覆盖其他(可能随机)。您应该将该 json 转换为对象数组:

[
    "imageSlider" : [
        "image" : [
            "imageId" : "1",
            "imageName" : "germany1",
            "imageBigName" : "germany1_BIG",
            "imageRights" : "Peter"
        ],
            "image" : [
            "imageId" : "2",
            "imageName" : "germany2",
            "imageBigName" : "germany2_BIG",
            "imageRights" : "Peter"
        ]
    ]
]

还应提供CountryModel 的其他键,因为它们都是非可选的。

【讨论】:

以上是关于如何快速反序列化 JSON的主要内容,如果未能解决你的问题,请参考以下文章

.Net Core 5.0 Json序列化和反序列化 | System.Text.Json 的json序列化和反序列化

利用fastjson反序列化json为对象和对象数组

如何反序列化json空数组

如何使用 Jackson 反序列化来自 json 对象的对象数组

如何反序列化包含多维数组的json对象?

如何反序列化 JSON 数据?