web-dev-qa-db-fra.com

Comment exclure des propriétés de Swift 4's Codable

Les nouveaux protocoles Encodable/Decodable de Swfit 4 rendent la sérialisation JSON (de) plus agréable. Cependant, je n'ai pas encore trouvé le moyen d'avoir un contrôle précis sur les propriétés qui devraient être codées et celles qui devraient être décodées.

J'ai remarqué qu'exclure la propriété de la variable CodingKeys qui l'accompagne l'exclut complètement du processus, mais existe-t-il un moyen d'avoir un contrôle plus fin?

45
RamwiseMatt

La liste des clés à encoder/décoder est contrôlée par un type appelé CodingKeys. Le compilateur peut synthétiser ceci pour vous mais peut toujours le remplacer.

Disons que vous ne voulez pas encoder/décoder la propriété nickname:

struct Person: Codable {
    var firstName: String
    var lastName: String
    var nickname: String?

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
    }
}

Ceci exclura nickname lors du codage et décodage.


Si vous voulez qu'il soit asymétrique (c'est-à-dire encoder mais pas décoder ou vice versa), vous devez fournir vos propres implémentations de encode(with encoder: ) et init(from decoder: ):

struct Person: Codable {
    var firstName: String
    var lastName: String

    // Since fullName is a computed property, it's excluded by default
    var fullName: String {
        return firstName + " " + lastName
    }

    private enum CodingKeys: String, CodingKey {
        case firstName
        case lastName
        case fullName
    }

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        firstName = try container.decode(String.self, forKey: .firstName)
        lastName = try container.decode(String.self, forKey: .lastName)
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(firstName, forKey: .firstName)
        try container.encode(lastName, forKey: .lastName)
        try container.encode(fullName, forKey: .fullName)
    }
}
86
Code Different

J'ai utilisé le protocole et son extension avec AssociatedObject pour définir et obtenir une propriété image (ou toute propriété devant être exclue de Codable).

Avec cela, nous n'avons pas à implémenter nos propres encodeurs et décodeurs

Voici le code, en gardant le code pertinent pour plus de simplicité:

protocol SCAttachmentModelProtocol{
    var image:UIImage? {get set}
    var anotherProperty:Int {get set}
}
extension SCAttachmentModelProtocol where Self: SCAttachmentUploadRequestModel{
    var image:UIImage? {
        set{
            //Use associated object property to set it
        }
        get{
            //Use associated object property to get it
        }
    }
}
class SCAttachmentUploadRequestModel : SCAttachmentModelProtocol, Codable{
    var anotherProperty:Int
}

Maintenant, chaque fois que nous voulons accéder à la propriété Image, nous pouvons utiliser l'objet confirmant le protocole (SCAttachmentModelProtocol).

0
infiniteLoop

Bien que cette peut être faite, elle finit par être très unSwifty _ et même un_JSON. Je pense que je vois d'où vous venez, le concept de #ids est répandu dans HTML, mais il est rarement transféré dans le monde de JSON que je considère comme une bonne chose _ (TM). 

Certaines structures Codable pourront analyser votre fichier JSON sans problème si vous le restructurez à l’aide de hachages récursifs, c’est-à-dire si votre recipe contient uniquement un tableau de ingredients qui contient (un ou plusieurs) ingredient_info. De cette façon, l'analyseur vous aidera en premier lieu à assembler votre réseau et il vous suffira de fournir des backlinks via une simple traversée de la structure si vous en avez vraiment besoin. Etant donné que cela nécessite une refonte complète de votre JSONet votre structure de données, je ne fais que dessiner l’idée pour vous d’y réfléchir. Si vous le jugez acceptable, veuillez me l'indiquer dans les commentaires, je pourrais le développer davantage, mais selon les circonstances, il se peut que vous ne soyez pas libre de changer l'un ou l'autre.

0
Patru

Si nous devons exclure le décodage d'un couple de propriétés d'un grand ensemble de propriétés dans la structure, déclarez-les en tant que propriétés facultatives. Code pour décompresser les options est moins que d’écrire beaucoup de clés sous CodingKey enum.

0