Быстрое преобразование Codable/Encodable в объект JSON

Недавно я включил Codable в проект, и чтобы получить объект JSON из типа, соответствующего Encodable, я придумал это расширение,

extension Encodable {

    /// Converting object to postable JSON
    func toJSON(_ encoder: JSONEncoder = JSONEncoder()) -> [String: Any] {
        guard let data = try? encoder.encode(self),
              let object = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
              let json = object as? [String: Any] else { return [:] }
        return json
    }
}

Это работает хорошо, но может ли быть лучший способ добиться того же?


person Kamran    schedule 22.10.2018    source источник
comment
Не связано, но вы можете объединить 3 отдельных состояния защиты в одну запятую, разделенную !!   -  person Prashant Tukadiya    schedule 22.10.2018
comment
Зачем тебе это нужно? Вы используете его с alamofire?   -  person Metin Guler    schedule 22.10.2018
comment
Я использую его с Alamofire. В некоторых случаях необходимо добавить/удалить ключ-значение из JSON объекта или заменить значения для некоторых ключей при отправке без изменения объекта.   -  person Kamran    schedule 22.10.2018
comment
Вы можете добавить коллекцию [String: Codable] к своему объекту для хранения ключей, которые могут изменяться. Тогда вам понадобится только JSONEncoder для преобразования объекта в данные json. Используйте эти данные для подготовки URLRequest и отправки его методу request Alamofire, который принимает протокол URLRequestConvertible.   -  person Metin Guler    schedule 22.10.2018
comment
Название функции вводит в заблуждение. Вы собираетесь конвертировать структуры в словарь через JSON. Никогда не игнорировать ошибки Codable и JSONSerialization. Сделайте функцию throw, уберите вопросительные знаки после try и передайте ошибку вызывающему.   -  person vadian    schedule 22.10.2018


Ответы (1)


Мое предложение состоит в том, чтобы назвать функцию toDictionary и передать возможные ошибки вызывающей стороне. Условный сбой нисходящего преобразования (несоответствие типов) выдается в оболочке с ошибкой кодирования typeMismatch de.

extension Encodable {

    /// Converting object to postable dictionary
    func toDictionary(_ encoder: JSONEncoder = JSONEncoder()) throws -> [String: Any] {
        let data = try encoder.encode(self)
        let object = try JSONSerialization.jsonObject(with: data)
        guard let json = object as? [String: Any] else {
            let context = DecodingError.Context(codingPath: [], debugDescription: "Deserialized object is not a dictionary")
            throw DecodingError.typeMismatch(type(of: object), context)
        }
        return json
    }
}
person vadian    schedule 22.10.2018