Search code examples
jsonswiftparsingcodableheterogeneous-array

Decoding Heterogeneous Array


I found a lot of examples concerning the implementation to decode an array of heterogeneous objects, but they don't really fit with my situation.

Here is my JSON :

{
  "response": [
    {
      "label": "Shore",
      "marineReports": [
        {
          "id": 1,
          "label": "Label"
        },
        {
          "id": 2,
          "label": "Label"
        }
      ]
    },
    {
      "label": "Open Sea",
      "marineReports": [
        {
          "id": 0,
          "label": "Label"
        },
        {
          "id": 0,
          "label": "Label"
        }
      ]
    },
    {
      "label": "Offshore",
      "marineReports": [
        {
          "id": 3,
          "label": "Label"
        },
        {
          "id": 3,
          "label": "Label"
        },
        {
          "id": 3,
          "label": "Label"
        }
      ]
    },
    {
      "label": "Special Reports",
      "specialReports": [
        {
          "label": "Atlantic-Channel",
          "reports": [
            {
              "id": 12,
              "label": "Offshore Atlantic"
            },
            {
              "id": 17,
              "label": "Channel"
            }
          ]
        }
      ]
    }
  ]
}

Here is what I implemented at first :

struct ResponseSea: Codable {
    let result: [SeaArea]
}

struct SeaArea: Codable {
    var label: String
    var reports: [MarineReport]

    struct MarineReport: Codable {
        var id: Int
        var label: String
    }
}

But then I figured out that the last object in the result array is different from the others. How can I implement a custom parsing logic for a specific object in an array of same object type ?


Solution

  • Based on your JSON it should be like this:

    struct RootObject: Codable {
        let response: [Response]
    }
    
    struct Response: Codable {
        let label: String
        let marineReports: [Report]?
        let specialReports: [SpecialReport]?
    }
    
    struct Report: Codable {
        let id: Int
        let label: String
    }
    
    struct SpecialReport: Codable {
        let label: String
        let reports: [Report]
    }
    

    marineReports and specialReports are optional since they may be absent.