简体   繁体   English

Swift:从包含字典的 JSON 创建可解码 model

[英]Swift: Create Decodable model from JSON which contains Dictionary in a Dictionary

I've stuck with creating a model to decode JSON file.我一直坚持创建 model 来解码 JSON 文件。 The structure of the file is presented in the picture:文件结构如图所示:

在此处输入图像描述

The problem I faced is decoding versionsListByTeams -> 1155 -> V1.0.4 .我面临的问题是解码versionsListByTeams -> 1155 -> V1.0.4 For the rest part my model looks like that:对于 rest 部分,我的 model 看起来像这样:

struct Settings: Decodable {
    let enabled: Bool
    let speed: Double
    let connections: Int
    let versionsListByHWVersion: [String: HWVersion]; struct HWVersion: Decodable {
        let version: String
        let binFile: String
        let jsonFile: String
    }
    let versionsListByTeams: [Int: Team]; struct Team: Decodable {
        let fotaEnabled: Bool
        // [String: HWVersion] <== what should be here?
    }
}

In case if you are still looking for a solution, slightly clunky way of doing this could be: (totally got inspired from the excellent answer of this post: How to get the nondecoded attributes from a Decoder container in Swift 4? )如果您仍在寻找解决方案,那么稍微笨拙的方法可能是:(完全从这篇文章的优秀答案中得到启发: How to get the nondecoded attributes from a Decoder container in Swift 4?

struct UnknownCodingKey: CodingKey {

    init?(stringValue: String) { self.stringValue = stringValue }
    let stringValue: String

    init?(intValue: Int) {return nil  }
    var intValue: Int? { return nil }
}

struct Team:Codable {

   var fotaEnabled:Bool
   var version: String
   var info : HWVersion?

   init(from decoder: Decoder) throws {
    
       self.fotaEnabled    = true
       self.version        = ""

       let container       = try decoder.container(keyedBy: UnknownCodingKey.self)
       for key in container.allKeys {
        
            if let boolValue = try? container.decode(Bool.self, forKey: key) {
                self.fotaEnabled = boolValue
            
            } else if let dataValue = try? container.decode(HWVersion.self, forKey: key) {
                self.version    = key.stringValue
                self.info       = dataValue
            
            } else {
                continue
            }
        }
    
     }
}

You need to create another struct like this to resolve repeat declaration您需要创建另一个这样的结构来解决重复声明

    struct Settings: Decodable {
    let enabled: Bool
    let speed: Double
    let connections: Int
    let versionsListByHWVersion: [String: HWVersion]
    let versionsListByTeams: [Int: VersionsListByTeams]
    
}
struct HWVersion: Decodable {
    let version: String
    let binFile: String
    let jsonFile: String
}
struct  VersionsListByTeams: Decodable {
    let fotaEnabled: Bool
    let versions: [String: HWVersion]
}

You can instantly parse JSON with https://app.quicktype.io/ .您可以立即使用https://app.quicktype.io/ 解析 JSON

paste your Json in this website and it will provide you complete model.将您的 Json 粘贴到本网站,它将为您提供完整的 model。

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

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