Search code examples
iosjsonswiftswift4jsondecoder

Swift 4 JSONDecoder Utility Function for Arbitrary Struct


I'm trying to create a utility function which given some Data and a struct which conforms to Decodable can decode the JSON data into the struct as follows:

func decodeDataToModel(data : Data?, model : Decodable) -> Decodable? {
    guard let data = data else { return nil }
    let object : Decodable?
    do {
       object = try JSONDecoder().decode(model, from: data)
    } catch let decodeErr {
       print("Unable to decode", decodeErr)
    }
    return object
}

This throws the error: Cannot invoke decode with an argument list of type (Decodable, from: Data). How can I make this function work with any arbitrary struct that I can pass as the model?

For example if I have:

struct Person : Decodable {
   let id : Int
   let name: String
}

struct Animal : Decodable {
   let id : Int
   let noOfLegs: Int
}

I want to be able to use it like this

let animal = decodeDataToModel(someData, from: Animal.self)
let human = decodeDataToModel(someOtherData, from: Person.self)

Solution

  • You can try

    func decodeDataToModel<T:Decodable>(data : Data?,ele:T.Type) -> T? {
        guard let data = data else { return nil } 
        do {
            let object = try JSONDecoder().decode(T.self, from: data)
            return object
        } catch  {
            print("Unable to decode", error)
        }
        return nil
    }
    

    Call

    let animal = decodeDataToModel(data:<#animaData#>, ele: Animal.self)