问题
This is the exact error
I get:
valueNotFound(Foundation.Data, Swift.DecodingError.Context(codingPath: [_PlistKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "wishData", intValue: nil), _PlistKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "image", intValue: nil)], debugDescription: "Expected Data value but found null instead.", underlyingError: nil))
Details:
I have two custom strcuts
:
Wishlist
:
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)
}
}
And Wish
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)
}
}
Setting
to UserDefaults
works without any error but getting
fires the error above
:
func getDataSourceArray() -> [Wishlist]? {
if let data = self.value(forKey: Keys.dataSourceKey) as? Data {
do {
_ = try PropertyListDecoder().decode(Array < Wishlist > .self, from: data) as [Wishlist]
} catch let error {
print(error)
}
if let dataSourceArray =
try? PropertyListDecoder().decode(Array < Wishlist > .self, from: data) as[Wishlist] {
return dataSourceArray
}
}
return nil
}
I know this might be quite confusing so let me know if there is anything you need to know. Im stuck here and have no idea what the problem is..
回答1:
Image data is nil
"image", intValue: nil)], debugDescription: "Expected Data value but found null instead."
so alter code in init(from decoder: Decoder) throws {
if let data = try? values.decodeIfPresent(Data.self, forKey: .image),let image = UIImage(data: data) {
self.image = image
}
With
public var image: UIImage?
and in your custom init do
, image: UIImage? = nil
Also change
try container.encode(image.pngData(), forKey: .image)
to
if let img = image , let im = img.pngData() {
try container.encode(im, forKey: .image)
}
来源:https://stackoverflow.com/questions/62941032/value-not-found-when-retrieving-from-userdefaults