0

I've stuck with creating a model to decode JSON file. The structure of the file is presented in the picture:

enter image description here

The problem I faced is decoding versionsListByTeams -> 1155 -> V1.0.4. For the rest part my model looks like that:

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?
    }
}
Volodymyr
  • 1,192
  • 21
  • 42

3 Answers3

1

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?)

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
            }
        }
    
     }
}
luckystars
  • 1,704
  • 12
  • 12
0

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]
}
Jawad Ali
  • 13,556
  • 3
  • 32
  • 49
  • how this answer differs from my question? The problem is that I don't have a parameter `versions` – Volodymyr Jul 07 '20 at 07:50
  • "No value associated with key CodingKeys(stringValue: \"versions\", intValue: nil) (\"versions\").", underlyingError: nil)) – Volodymyr Jul 07 '20 at 07:52
0

You can instantly parse JSON with https://app.quicktype.io/.

paste your Json in this website and it will provide you complete model.

  • sorry, but it doesn't work for me. I have already tried that service but it gives me hardcoded model like this: `// MARK: - V10 struct V10 { let version: String let binFile: String let jsonFile: String } // MARK: - VersionsListByTeams struct VersionsListByTeams { let the1155: The1155 let the675, the1154: The1150 let the1163: The1163 let the1150: The1150 }` which is not I wanted to achieve – Volodymyr Jul 08 '20 at 13:09