Handling null values in json

Hi All,

I've encountered a strange JSON file where i get some list of "null" values in it. Not sure how to parse this json without any crashes.

let tc = #"""
  {
   "testCases" : [[[{
 "id" : 1234,
 "uri" : "/user/1234",
 "name" : "FirstName.LastName"
 }], null, null, null ]],
  }
"""#
struct TestCase:Decodable {
  let id:UInt64
  let uri:String
  let name:String

}

struct TestCases:Decodable {
  let tc:[[[TestCase]]]
  
  enum CodingKeys:String, CodingKey {
    case tc = "testCases"
  }
  init(from decoder: Decoder) throws {
    let values =  try decoder.container(keyedBy: CodingKeys.self)
    if let tmp = try values.decodeIfPresent([[[TestCase]]].self, forKey: .tc) {
      self.tc = tmp
    } else {
      self.tc = [[[]]]
    }
  }
}

let dc = JSONDecoder()
try dc.decode(TestCases.self, from: Data(tc.utf8))

I did try to use decodeIfPresent but looks like only works on parent level, if there are any null values in the nested structure it doesn't handle it.

The above code crashes with the given input
Where as it passes if we remove the null values in the json.

let tc = #"""
  {
   "testCases" : [[[{
 "id" : 1234,
 "uri" : "/user/1234",
 "name" : "FirstName.LastName"
 }] ]],
  }
"""#

You can do without any custom decoding logic here:

struct Foo: Codable {
    struct Bar: Codable {
       let id: Int
       let uri: String
       let name: String
    }
    var testCases: [[[Bar]?]]
}

Thank you @tera. Your solution works only for the json which doesn't contain any null values. But crashes for if there any Null values in the json.

I improvised on your suggestion and figured the following code works for the null values aswell.
Input

let tc = #"""
  {
    "testCases": [
        [
            [
                {
                    "id": 13559745,
                    "uri": "/item/13559745",
                    "name": "FooBar"
                }
            ],
            null,
            null,
            null
        ]
    ]
}
"""#

Modified code

struct Foo: Codable {
  struct Bar: Codable {
    struct Dog: Codable {
      let id: Int
      let uri: String
      let name: String
    }
  }
  var testCases: [[[Bar.Dog?]?]]
}

let dc = JSONDecoder()
try dc.decode(Foo.self, from: Data(tc.utf8))