Hi,
I'm trying to create a generic container that I can back up to disk as needed and that I can restore later.
I first set up the following extensions
extension Data {
public func deserialize<T:Codable>() -> T? {
var lRet:T? = nil
if let lValue = try? JSONDecoder().decode(T.self, from: self) {
lRet = lValue
} else if let lValue = try? JSONDecoder().decode([T].self, from: self) {
lRet = lValue.first
}
return lRet
}
}
extension Encodable {
public func serialize() -> Data? {
var lRet:Data? = nil
if let lData = try? JSONEncoder().encode(self) {
lRet = lData
} else if let lData = try? JSONEncoder().encode([self]) {
lRet = lData
}
return lRet
}
}
I then created a class to hold different keys with different values
public class Store {
private var dict:[String:Data] = [:]
public init() {
}
public init(_ pData:Data) {
self.load(pData)
}
public subscript<T>(_ pKey:String) -> T? where T:Codable {
get {
var lRet:T? = nil
if let lData = dict[pKey], let lValue:T = lData.deserialize() {
lRet = lValue
}
return lRet
}
set(pValue) {
if let lValue = pValue?.serialize() {
dict[pKey] = lValue
} else {
dict.removeValue(forKey: pKey)
}
}
}
public func data() -> Data {
var lRet = Data()
if let lData = dict.serialize() {
lRet = lData
}
return lRet
}
public func load(_ pData:Data) {
if let lDict:[String:Data] = pData.deserialize() {
dict = lDict
}
}
}
And finally here is a piece of code to test
public class Test : Codable {
public var int:Int
public var string:String
public init(int pInt:Int, string pString:String) {
int = pInt
string = pString
}
}
let lStore = Store()
lStore["int"] = 100
lStore["string"] = "a string"
lStore["test"] = Test(int: 100, string: "just a test with class")
let lData = lStore.data()
let lNewStore = Store(lData)
let lInt:Int = lNewStore["int"] ?? 0
let lString:String = lNewStore["string"] ?? ""
let lTest:Test = lNewStore["test"] ?? Test(int: 0, string: "")
print("lInt = \(lInt), lString = \(lString), lTest=\(lTest)")
With basic types like Int
or String
it works fine
By cons when I try with a class I can manage to generate the corresponding Data and read it but it bug on the following lines
if let lData = dict[pKey], let lValue:T = lData.deserialize() {
lRet = lValue
}
For lValue
I have some thing like this:
And if I assign lValue to
lRet
, lRet
is nil
What should I do for the class to be deserialized properly?
I'm using Xcode Version 10.2.1 (10E1001) with Swift 5.0.1