web-dev-qa-db-fra.com

La classe codable n'est pas conforme au protocole Decodable

Pourquoi ai-je un message d'erreur de type "Signet" non conforme au protocole "Décodable"?

class Bookmark: Codable {
   weak var publication: Publication?
   var indexPath: [Int]
   var locationInText = 0

   enum CodingKeys: String, CodingKey {
      case indexPath
      case locationInText
   }

   init(publication: Publication?, indexPath: [Int]) {
      self.publication = publication
      self.indexPath = indexPath
   }
}

Je ne souhaite pas enregistrer la publication var car la publication est propriétaire du signet, mais le signet doit savoir à quelle publication il appartient. Le décodage init of Publication définira la référence du signet sur elle-même.

17
Melodius

Pourquoi est-ce que je reçois un message d'erreur "Le type 'Signet' n'est pas conforme au protocole 'Décodable'"

C'est soit parce que la publication n'est pas décodable (vous n'avez pas montré ce que c'est, il est donc difficile de le savoir) ou à cause de la désignation weak sur publication.

Quoi qu'il en soit, c'est facile à corriger: il vous suffit d'implémenter init(from:) pour terminer l'implémentation de Decodable; le compilateur vous dit simplement que cette implémentation ne peut pas être synthétisée.

16
matt

Le compilateur ne peut pas synthétiser la méthode init(from:) requise en raison de la référence weak. Vous devez donc l'écrire vous-même.

class Bookmark: Codable {
    weak var publication: Publication?
    var indexPath: [Int]
    var locationInText = 0

    private enum CodingKeys: String, CodingKey {
        case indexPath
        case locationInText
    }

    init(publication: Publication?, indexPath: [Int]) {
        self.publication = publication
        self.indexPath = indexPath
    }

    required init(from decoder:Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        indexPath = try values.decode([Int].self, forKey: .indexPath)
        locationInText = try values.decode(Int.self, forKey: .locationInText)
    }
}
25
Dávid Pásztor

Avec le recul, j'ai reçu une erreur similaire en essayant de définir Codeable dans ma classe qui consistait en variables de type NSNumber. Voir l'image ci-dessous:

 enter image description here

Remplacer NSNumber par le type de données primitif Int a résolu le problème. Voir ci-dessous:

 enter image description here

J'imagine que cela pourrait être vrai pour d'autres types de données nécessitant un pontage vers des types de valeurs de bibliothèque standard Swift tels que NSString, NSArray, etc.

13
iOSer

Une autre raison pour laquelle vous pourriez recevoir ce message est si votre énumération CodingKeys n'est pas exhaustive. Si vous avez trois propriétés dans le type de données, votre énumération CodingKeys doit également comporter trois observations de propriété/nom.

5
mikepj

insort, Lors de l’implémentation de Codable, toutes les propriétés qui n’ont pas de type de données primitif (type de classe moyen ou pouvant être de classe objectif-c) doivent être codables.

   weak var publication: Publication?

dans ce cas, la publication est de type classe, donc la publication doit avoir implémenté Codable

1
kalpesh jetani

J'ai eu un problème similaire que je suis tombé sur ce correctif à. Comme je suis nouveau à Swift, je ne sais pas pourquoi cela fonctionne! Si quelqu'un sait, j'apprécierais le savoir.

J'ai changé ceci:

let id, type: Int

pour ça:

let id: Int
let type: Int
0
ThunderGrad