2017-07-26 3 views
6

Ich habe die folgende Struktur ...Swift Kodierbare Protokoll ... Codierung/Decodierung NSCoding Klassen

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) 
    } 
} 

eine Photo Encoding irgendwie ...

Optional nicht kodierbaren nicht entspricht, weil UIImage tut entsprechen nicht Codieren

Decodierung schlägt fehl mit ...

Key nicht als erwartet nicht optionalen Typen Optional für Codierungsschlüssel \ "image \" "))

Gibt es eine Möglichkeit Swift Objekte zu kodieren, die umfassen NSObject Unterklasse Eigenschaften gefunden, die NSCoding entsprechen (UIImage, UIColor, usw.)?

+3

Sie haben benutzerdefinierten Encoder/Decoder-Code zu schreiben, um die Objekte zu archivieren/dearchivieren zu und von 'Data'. Bitte lesen Sie [Encoding and Decoding Custom Types] (https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types) – vadian

Antwort

7

Dank @vadian mich in Richtung der Codierung zeigen/Decodierung 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

Also macht 'Codable' eigentlich nichts leichter, wenn" benutzerdefinierte Typen "verwendet werden ? : - | – d4Rk

+0

Gut - es erlaubt Ihnen, Nicht-'NSObject' Unterklassen (enums & Strukturen) zu kodieren/zu decodieren –

+0

@AshleyMills, ich erhalte diesen Fehler" Typ 'Foto' entspricht nicht Protokoll 'Decodierbar' "beim Kopieren dieses Codes in meine Datei. –