Как я могу расширить Decodable для инициализации из словаря?

Я хочу расширить Decodable, чтобы создать новый экземпляр класса Codable из словаря значений.

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

Я получаю сообщение об ошибке Value of type 'Self' has no member 'type' в строке, которая начинается с let newSelf = ...

Как я должен указать тип для использования здесь?


person Josh Paradroid    schedule 22.02.2019    source источник


Ответы (1)


self.type должен быть конкретным типом, а не протоколом. И вы все равно не можете создать экземпляр Decodable.

Что вы можете сделать, так это создать общий метод decode, который, например, принимает словарь в качестве параметра.

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)
person vadian    schedule 22.02.2019
comment
Идеальный! Спасибо. - person Josh Paradroid; 22.02.2019