2017-07-26 6 views
6

je le struct suivant ...protocole Swift codables ... encodage/décodage des classes NSCoding

struct Photo: Codable { 

    let hasShadow: Bool 
    let image: UIImage? 

    enum CodingKeys: String, CodingKey { 
     case `self`, hasShadow, image 
    } 

    init(hasShadow: Bool, image: UIImage?) { 
     self.hasShadow = hasShadow 
     self.image = image 
    } 

    init(from decoder: Decoder) throws { 
     let container = try decoder.container(keyedBy: CodingKeys.self) 
     hasShadow = try container.decode(Bool.self, forKey: .hasShadow) 

     // This fails 
     image = try container.decode(UIImage?.self, forKey: .image) 
    } 

    func encode(to encoder: Encoder) throws { 
     var container = encoder.container(keyedBy: CodingKeys.self) 
     try container.encode(hasShadow, forKey: .hasShadow) 

     // This also fails 
     try container.encode(image, forKey: .image) 
    } 
} 

Encoding un Photo échoue avec ...

option ne se conforme pas à codable parce UIImage ne pas conforme aux codable

décodage échoue avec ...

Clé introuvable en attendant type non-option en option pour codage « image \ » clé \ "))

Yat-il un moyen d'encoder des objets Swift qui incluent NSObject propriétés de sous-classe qui sont conformes à NSCoding (UIImage, UIColor, etc.)?

+3

Vous devez écrire encode/code de décodage personnalisé pour archiver/décompressez les objets et de 'data'. Veuillez lire [Encodage et décodage des types personnalisés] (https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types) – vadian

Répondre

7

Merci à @vadian me pointant dans la direction de codage/décodage Data ...

class Photo: Codable { 

    let hasShadow: Bool 
    let image: UIImage? 

    enum CodingKeys: String, CodingKey { 
     case `self`, hasShadow, imageData 
    } 

    init(hasShadow: Bool, image: UIImage?) { 
     self.hasShadow = hasShadow 
     self.image = image 
    } 

    required init(from decoder: Decoder) throws { 
     let container = try decoder.container(keyedBy: CodingKeys.self) 
     hasShadow = try container.decode(Bool.self, forKey: .hasShadow) 

     if let imageData = try container.decodeIfPresent(Data.self, forKey: .imageData) { 
      image = NSKeyedUnarchiver.unarchiveObject(with: imageData) as? UIImage 
     } else { 
      image = nil 
     } 
    } 

    func encode(to encoder: Encoder) throws { 
     var container = encoder.container(keyedBy: CodingKeys.self) 
     try container.encode(hasShadow, forKey: .hasShadow) 

     if let image = image { 
      let imageData = NSKeyedArchiver.archivedData(withRootObject: image) 
      try container.encode(imageData, forKey: .imageData) 
     } 
    } 
} 
+1

Donc, à la fin, 'Codable' ne facilite pas vraiment l'utilisation de" types personnalisés " ? : - | – d4Rk

+0

Eh bien - il vous permet d'encoder/décoder des sous-classes non -NSObject (enums & structs) –

+0

@AshleyMills, je reçois cette erreur "Type 'Photo' n'est pas conforme au protocole 'Decodable'" en copiant ce code dans mon fichier. –