Adding functionality to JSONDecoder (json decoding)

I am currently working on an app that has a lot of legacy data from the backend. This means types are very unreliable. I can get a boolean like these examples "canJump": "1" "canJump": 0 "canJump": "true" "canJump": false. So I have been pondering about good ways to handle decoding this. I would like to avoid:

if let bool = try? container.decode(Bool.self, forKey: .jump) {
  self.canJump = bool
}

if let boolAsString = try? container.decode(String.self, forKey: .jump) {
  if boolAsString == "true" || boolAsString == "false" {
    self.canJump = Bool(boolAsString)
  }
}

etc. in every single custom decoder. So I tried an extension:

extension KeyedDecodingContainer {    
    func decodeWithUnknownTypes(_ type: Bool.Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> Bool {
        do {
            return try decode(Bool.self, forKey: key)
        } catch DecodingError.typeMismatch {}
        
        do {
            let string = try decode(String.self, forKey: key)
            return Bool(string.lowercased())
        } catch DecodingError.typeMismatch {}
        
        do {
            let int = try decode(Int.self, forKey: key)
            if int == 1 {
                return true
            }
            if int == 0 {
                return false
            }
        }
        
        throw DecodingError.typeMismatch
    }
}

(not entirely finished). The above almost does the trick, but it still leaves me having to implement custom decoders in basically all my backend calls past and future. I would love it if someone has an idea of how I could write it, so I can simply use a Decodable struct, and it would automagically accept 1 as a Bool. Can I maybe override the decode method of KeyedDecodingContainer and still get the original function as a "first try"?

If I understand correctly, you don't know in fact the exact type of canJump ?

Have a look here to use unknown type: https://stackoverflow.com/questions/52896731/how-to-use-jsondecoder-to-decode-json-with-unknown-type

Did you try to use Any as type in struct. Here is a simple illustration (in playground):

struct Test {
    var value: Any
}

let v1 = Test(value: 1 as Any)
let v2 = Test(value: true as Any)
let v3 = Test(value: "true" as Any)
let tests = [v1, v2, v3]

var result : Bool
for (i, v) in tests.enumerated() {
    if let valueInt = v.value as? Int { print("An Int for v\(i+1)") ; result = valueInt == 1 }
    if let valueBool = v.value as? Bool { print("A Bool for v\(i+1)") ; result = valueBool }
    if let valueString = v.value as? String { print("A String for v\(i+1)") ; result = valueString == "true" }
}

Which yields:

An Int for v1
A Bool for v2
A String for v3
Adding functionality to JSONDecoder (json decoding)
 
 
Q