2017-07-26 158 views
6

我有以下結構...夫特可編碼協議...編碼/解碼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) 
    } 
} 

編碼一個Photo失敗,...

可選不符合可編碼因爲UIImage的確實 不符合可編碼

解碼失敗...

鑰匙未發現期待非可選類型可選時 編碼鍵\「圖像\」「))

有沒有辦法來編碼斯威夫特對象包括符合NSCodingNSObject子類的屬性(UIImageUIColor等)?

+3

你必須編寫自定義編碼/解碼碼存檔/解除存檔的對象,並從'Data'。請參閱[編碼和解碼定義類型(https://developer.apple.com/documentation/foundation/archives_and_serialization/encoding_and_decoding_custom_types) – vadian

回答

7

由於@vadian指着我的編碼/解碼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

那麼到底'Codable'並沒有真正做任何事情變得更容易,使用「自定義類型」時, ? : - | – d4Rk

+0

好 - 它可以讓你編碼/解碼非'NSObject'子類(枚舉和結構) –

+0

@AshleyMills,我得到這個錯誤「類型‘照片’不符合協議‘可解’」,而在複製這段代碼我文件。 –