Josh Paradroid
Josh Paradroid

Reputation: 1414

How can I extend Decodable to initialise from dictionary?

I want to extend Decodable so I can create a new instance of a Codable class from a dictionary of values.

extension Decodable {
    init(from dictionary: [String : Codable]) throws {
        let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
        let newSelf = try JSONDecoder().decode(self.type, from: data)

        self = newSelf
    }
}

I'm getting the error Value of type 'Self' has no member 'type' on the line that starts with let newSelf = ...

How should I provide the type to use here?

Upvotes: 0

Views: 1105

Answers (1)

vadian
vadian

Reputation: 285074

self.type must be a concrete type, not a protocol. And you cannot create an instance of Decodable anyway.

What you can do is to create a generic decode method which takes a dictionary as parameter for example

func decode<T : Decodable>(from dictionary: [String : Decodable]) throws -> T {
    let data = try JSONSerialization.data(withJSONObject: dictionary)
    return try JSONDecoder().decode(T.self, from: data)
}


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

let dict : [String:Decodable] = ["name" : "Foo", "age" : 30]

let person : Person = try! decode(from: dict)

Upvotes: 2

Related Questions