Custom Struct: Type does not conform to protocol 'Decodable'
我希望能够将
1 2 3 4 5 6 7 8 | struct Wishlist: Codable { var name: String var image: UIImage var wishData: [Wish] var color: UIColor var textColor: UIColor var index: Int } |
但是这给了我这个
Type 'Wishlist' does not conform to protocol 'Decodable'
这是我的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | class Wish: NSObject { public var wishName : String? public var checkedStatus : Bool? public var wishLink : String? public var wishPrice : String? public var wishNote : String? public var wishImage : UIImage? init(withWishName name: String, link: String, price: String, note: String, image: UIImage, checked: Bool) { super.init() wishName = name checkedStatus = checked wishLink = link wishPrice = price wishNote = note wishImage = image } } |
我在这里做错什么了吗?
您将需要使
但是由于
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | struct Wishlist: Codable { var name: String var image: UIImage var wishes: [Wish] var color: UIColor var textColor: UIColor var index: Int enum CodingKeys: String, CodingKey { case name, image, wishData, color, textColor, index } init(name: String, image: UIImage, wishes: [Wish], color: UIColor, textColor: UIColor, index: Int) { self.name = name self.image = image self.wishes = wishes self.color = color self.textColor = textColor self.index = index } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) name = try values.decode(String.self, forKey: .name) wishes = try values.decode([Wish].self, forKey: .wishData) color = try values.decode(Color.self, forKey: .color).uiColor textColor = try values.decode(Color.self, forKey: .textColor).uiColor index = try values.decode(Int.self, forKey: .index) let data = try values.decode(Data.self, forKey: .image) guard let image = UIImage(data: data) else { throw DecodingError.dataCorruptedError(forKey: .image, in: values, debugDescription:"Invalid image data") } self.image = image } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) try container.encode(wishes, forKey: .wishData) try container.encode(Color(uiColor: color), forKey: .color) try container.encode(Color(uiColor: textColor), forKey: .textColor) try container.encode(index, forKey: .index) try container.encode(image.pngData(), forKey: .image) } } struct Wish: Codable { public var name: String public var checkedStatus: Bool public var link: String public var price: String public var note: String public var image: UIImage init(name: String, link: String, price: String, note: String, image: UIImage, checkedStatus: Bool) { self.name = name self.checkedStatus = checkedStatus self.link = link self.price = price self.note = note self.image = image } enum CodingKeys: String, CodingKey { case name, checkedStatus, link, price, note, image } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) name = try values.decode(String.self, forKey: .name) checkedStatus = try values.decode(Bool.self, forKey: .checkedStatus) link = try values.decode(String.self, forKey: .link) price = try values.decode(String.self, forKey: .price) note = try values.decode(String.self, forKey: .note) let data = try values.decode(Data.self, forKey: .image) guard let image = UIImage(data: data) else { throw DecodingError.dataCorruptedError(forKey: .image, in: values, debugDescription:"Invalid image data") } self.image = image } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(name, forKey: .name) try container.encode(checkedStatus, forKey: .checkedStatus) try container.encode(link, forKey: .link) try container.encode(price, forKey: .price) try container.encode(note, forKey: .note) try container.encode(image.pngData(), forKey: .image) } } |
在哪里将其用作编码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | struct Color: Codable { let red: CGFloat let green: CGFloat let blue: CGFloat let alpha: CGFloat init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) { self.red = red self.green = green self.blue = blue self.alpha = alpha } init(uiColor: UIColor) { var red: CGFloat = 0 var green: CGFloat = 0 var blue: CGFloat = 0 var alpha: CGFloat = 0 uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha) self.red = red self.green = green self.blue = blue self.alpha = alpha } var uiColor: UIColor { UIColor(red: red, green: green, blue: blue, alpha: alpha) } } |
注意,我做了几个不相关的更改:
-
我都做了这两个
struct 。除非必要,否则我不会介绍引用类型(更少的NSObject 子类)。 -
我简化了一些属性名称。例如。在
Wish 中,我们通常不会在属性名称中使用Wish 前缀。我也不会使用"数据"?除非实际上是Data 。 -
我更新了
init 方法以使用标准命名约定。
在您的情况下,
应该添加
错误的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public struct DtClip: Codable { // MARK: Properties public var video: String? public var preview: String? public var clip: String? public var trailer: Any? enum CodingKeys: String, CodingKey { case video ="video" case preview ="preview" case clip ="clip" } } |
从示例中的
我们知道
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | public struct DtClip: Codable { // MARK: Properties public var video: String? public var preview: String? public var clip: String? public var trailer: Trailer? enum CodingKeys: String, CodingKey { case video ="video" case preview ="preview" case clip ="clip" case trailer ="trailer" } } public struct Trailer: Codable { // MARK: Properties public var name: String? public var id: Int? enum CodingKeys: String, CodingKey { case name, url } } |
另外,您的班级希望必须实现Codable协议