0

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
            }
        }
        
        return nil
    }
}

(not entirely finished). The above almost does the trick, but it still leaves me having to implement custom decoders in almost all my backend calls. 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"?

Mathias Egekvist
  • 358
  • 3
  • 14
  • Use a property wrapper – Alexander Jun 17 '21 at 19:47
  • I would like to see, how you would implement it with a property wrapper? Sadly are we still supporting iOS 12 but soon to be deprecated so maybe in a later release I could use your suggestion. – Mathias Egekvist Jun 18 '21 at 07:36
  • Have a look at what they do in this library: https://github.com/GottaGetSwifty/CodableWrappers – Alexander Jun 19 '21 at 15:24
  • Check this answer - https://stackoverflow.com/a/60246989/1974224 - it applies to decoding strings, but support for bools can be easily added. – Cristik Jun 19 '21 at 20:41
  • @Alexander, thank you - pretty cool library I will see if we can use later or maybe do some of the same. – Mathias Egekvist Jun 28 '21 at 06:44
  • @Cristik very true, I also considered doing a wrapper type, but I still think it's sub optimal in my case as I would basically need it everywhere. – Mathias Egekvist Jun 28 '21 at 06:45
  • @MathiasEgekvist then you might need a custom decoder, which can also translate to lots of code to replace `JSONDecoder`. – Cristik Jun 28 '21 at 06:47

0 Answers0