我尝试在此处通过Vadian实施解决方案:Make UIColor Codable
但是我遇到了一个我无法克服的错误。
这是上述解决方案的实现:
struct Color : Codable {
var red : CGFloat = 0.0, green: CGFloat = 0.0, blue: CGFloat = 0.0, alpha: CGFloat = 0.0
var uiColor : UIColor {
return UIColor(red: red, green: green, blue: blue, alpha: alpha)
}
init(uiColor : UIColor) {
uiColor.getRed(&red, green: &green, blue: &blue, alpha: &alpha)
}
}
struct Tasting: Codable {
private enum CodingKeys: String, CodingKey { case id, title, color, textColor, notes }
var id: Int
var title: String
var color : UIColor
var textColor : UIColor
var notes: String
init(id: Int, title: String, color : UIColor, textColor : UIColor, notes: String) {
self.id = id
self.title = title
self.color = color
self.textColor = textColor
self.notes = notes
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
title = try container.decode(String.self, forKey: .title)
color = try container.decode(Color.self, forKey: .color).uiColor
textColor = try container.decode(Color.self, forKey: .textColor).uiColor
notes = try container.decode(String.self, forKey: .notes)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(id, forKey: .id)
try container.encode(title, forKey: .title)
try container.encode(Color(uiColor: color), forKey: .color)
try container.encode(Color(uiColor: color), forKey: .textColor)
try container.encode(notes, forKey: .notes)
}
}
在这里:
//Encodes UIColor so it can be saved
let tastings = [
Tasting(id: 0, title: "(Delete this row after you add your first tasting!)", color: .green, textColor: .black, notes: "Add notes here.")
]
do {
let data = try JSONEncoder().encode(tastings)
print(String(data: data, encoding: .utf8)!)
let newTastings = try JSONDecoder().decode(Tasting.self, from: data)
print("newTastings \(newTastings)")
} catch {
print("newTastings \(error)")
}
然后将其保存到UserDefaults。
//Saves new brand to device memory
let savedTastings = tastings
UserDefaults.standard.set(savedTastings, forKey: "tastings")
这些是我得到的错误:
newTastings typeMismatch(Swift.Dictionary<Swift.String, Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Dictionary<String, Any> but found an array instead.", underlyingError: nil))
2019-07-25 11:38:05.909711-0700 WhiskyTasting[10601:3581697] [User Defaults] Attempt to set a non-property-list object (
"WhiskyTasting.Tasting(id: 0, title: \"(Delete this row after you add your first tasting!)\", color: UIExtendedSRGBColorSpace 0 1 0 1, textColor: UIExtendedGrayColorSpace 0 1, notes: \"Add notes here.\")"
) as an NSUserDefaults/CFPreferences value for key tastings
2019-07-25 11:38:05.910207-0700 WhiskyTasting[10601:3581697] ***
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attempt to insert non-property list object (
"WhiskyTasting.Tasting(id: 0, title: \"(Delete this row after you add your first tasting!)\", color: UIExtendedSRGBColorSpace 0 1 0 1, textColor: UIExtendedGrayColorSpace 0 1, notes: \"Add notes here.\")"
) for key tastings'
我希望大家都能看到我所缺少的简单错字。几天来一直在努力应对这种变化。
答案 0 :(得分:0)
错误与我的解决方案无关。
第一个错误告诉您该对象是数组。请阅读您的代码,tastings
显然是一个数组。
所以你必须解码一个数组
let newTastings = try JSONDecoder().decode([Tasting].self, from: data)
第二个错误告诉您,结构中的类型是不符合属性列表的类型。此类型为UIColor
。您不能将Tasting
实例保存到UserDefaults
,但是可以保存JSON- /或PropertyList编码的Tasting
实例。
let data = try JSONEncoder().encode(tastings)
UserDefaults.standard.set(data, forKey: "tastings")