I want to be able to save Dictionary of type [String:Codable] to plist and recover back as same. I tried this but it throws errors:
let dictionary:[String:Any] = ["point":CGPoint(1,1), "value": 10, "key" : "testKey"]
do {
let url = FileManager.default.temporaryDirectory.appendingPathComponent("test.plist")
try savePropertyList(dictionary, toURL: url)
buildFromPlist(url)
} catch {
print(error)
}
private func savePropertyList(_ plist: Any, toURL url:URL) throws
{
let plistData = try PropertyListSerialization.data(fromPropertyList: plist, format: .xml, options: 0)
try plistData.write(to: url)
}
private func buildFromPlist(_ url:URL)
{
do {
let data = try Data(contentsOf: url)
let decoder = PropertyListDecoder()
let dictionary = try decoder.decode([String:Decodable], from: data)
NSLog("\(dictionary)")
} catch {
NSLog("Error decoding \(error)")
}
}
But I get build errors in decode function:
Value of protocol type 'Decodable' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols
I wonder how I read back the dictionary I saved to plist file?
EDIT: Even savePropertyList fails at runtime with objects such as CGPoint and CGAffineTransform with the error -
"Property list invalid for format: 100 (property lists cannot contain objects of type 'CFType')" UserInfo={NSDebugDescription=Property list invalid for format: 100 (property lists cannot contain objects of type 'CFType')}
I wonder how can we write Codable objects to plist and recover back?
This cannot work because the type in the
decoder.decode
line must be a concrete type. And[String:Decodable]
without trailing.self
will throw another error.The goal of the
Codable
protocol is to serialize custom structs or classes so make your dictionary a structand encode this. In the decoding part write