问题:解码属于Parent和Child类的对象数组。
我阅读了很多关于这个主题的资料,但是我没有找到一个简单的解决方案。
我编码了一个类型属性,它提供了原始类的信息,但是我还没有找到在解码对象时使用它的方法。
原始数组的输出为:
解码数组的输出为:
我阅读了很多关于这个主题的资料,但是我没有找到一个简单的解决方案。
我编码了一个类型属性,它提供了原始类的信息,但是我还没有找到在解码对象时使用它的方法。
class Parent: Codable, CustomDebugStringConvertible {
var debugDescription: String {
return "[\(name)]"
}
var name: String
init(name: String) {
self.name = name
}
enum CodingKeys: CodingKey {
case name
case type
case age
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try! container.decode(String.self, forKey: .name)
let type = try! container.decode(String.self, forKey: .type)
print("Reading \(type)")
if type == "Child" {
try Child.init(from: decoder)
return
}
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode("Parent", forKey: .type)
try container.encode(name, forKey: .name)
}
}
class Child: Parent {
override var debugDescription: String {
return "[\(name) - \(age)]"
}
var age: Int
init(name: String, age: Int) {
self.age = age
super.init(name: name)
}
enum CodingKeys: CodingKey {
case name
case age
case type
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
age = try! container.decode(Int.self, forKey: .age)
let name = try! container.decode(String.self, forKey: .name)
super.init(name: name) // I think the problem is here!
}
override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode("Child", forKey: .type)
try container.encode(age, forKey: .age)
}
}
这是测试代码。
let array = [Parent(name: "p"), Child(name: "c",age: 2)]
print(array)
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let decoder = JSONDecoder()
do {
let jsonData = try encoder.encode(array)
let s = String(data: jsonData, encoding: .ascii)
print("Json Data \(s!)")
let decodedArray = try decoder.decode([Parent].self, from: jsonData)
print(decodedArray)
}
catch {
print(error.localizedDescription)
}
原始数组的输出为:
[[p], [c - 2]]
解码数组的输出为:
[[p], [c]]
如何更改父类和/或子类的init函数以正确解码对象?
显然,我的实际情况比这复杂得多。我必须编码/解码一个包含继承类数组的类。我尝试使用了这个:
https://github.com/IgorMuzyka/Type-Preserving-Coding-Adapter
显然,它在Parent、Child数组上运行良好,但如果数组位于另一个类中,则无法正常工作。 此外,我想学习一种解决方案,以便在其他情况下重用并避免包含不必要的外部库。
age
变量的地方。在调用super.init(name: name)
之后,我认为你应该调用self.init(name: name, age: age)
。你还应该删除self.init
中的name
参数,因为它已经在超类初始化器中设置了。 - andrijaself.init(name: name, age: age)
,因为你在这个便利初始化器中已经有了super
调用。 - andrija