es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Creando la clase Encodable mediante la inyección de una clase que cumpla exclusivamente con el protocolo Encodable.

Estoy construyendo un módulo de red que utiliza la clase Body que será codificada para servir como cuerpo de una solicitud de URL. Quiero inicializar Body con cualquier clase que cumpla con el protocolo Encodable, en mi caso es la clase MyDevice que cumple con DeviceEncodable, que es un protocolo que define todo lo que mi solicitud de URL necesita. La clase MyDevice ya hereda de otra clase llamada SpecialClass, por lo tanto, solo puedo conformarlo al protocolo porque Swift no permite la herencia de más de una clase. El problema es que cuando inicializo Body con DeviceEncodable obtengo el error “Error: El tipo ‘Body’ no cumple con el protocolo ‘Encodable'”. Entiendo que se debe a que DeviceEncodable puede ser una clase pero también algún otro protocolo que cumpla con él. ¿Cuál es la solución correcta para usar DeviceEncodable como una propiedad en la función de Body de manera que se codifique correctamente y sin la necesidad de heredar? Aquí está el código de ejemplo:

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para usar DeviceEncodable como una propiedad en la función Body, debes asegurarte de que cumpla con el protocolo Encodable. Dado que MyDevice ya cumple con DeviceEncodable, que hereda de Encodable, solo necesitas marcar MyDevice como Encodable implementando la función encode(to:). Aquí tienes un fragmento de código actualizado:

    class Body: Encodable {
        let device: DeviceEncodable
    
        init(_ deviceInfo: DeviceEncodable) {
            self.device = deviceInfo
        }
    
        enum CodingKeys: String, CodingKey {
            case device
        }
    }
    
    protocol DeviceEncodable: AnyObject, Encodable {
        var someSpecialProperty: String { get }
    }
    
    class MyDevice: SpecialClass, DeviceEncodable, Encodable {
        var someSpecialProperty: String = "special"
    
        enum CodingKeys: String, CodingKey {
            case someSpecialProperty
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.someSpecialProperty, forKey: .someSpecialProperty)
            try super.encode(to: encoder)
        }
    }
    
    class SpecialClass: Encodable {
        var someOtherProperty: String = "other"
    
        enum CodingKeys: String, CodingKey {
            case someOtherProperty
        }
    
        func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.someOtherProperty, forKey: .someOtherProperty)
        }
    }
    

    En el código actualizado, MyDevice implementa la función encode(to:) para codificar someSpecialProperty y también llama a la función encode(to:) de su superclase. Body y MyDevice también definen el enum CodingKeys para especificar las claves de las propiedades codificadas.

Comments are closed.