概要
タイトルの通り、以下のようなJSONをencodeしようとしてハマったため、こちらの記事に簡単にメモしておきます。
{
"value": 5,
"list": [
{
"className": "A"
},
{
"className": "B"
}
]
}
実装例。containerをネストさせます。
import Foundation
protocol P : Encodable {}
class A : P {
var className = "A"
}
class B : P {
var className = "B"
}
class Data : Encodable {
var value: Int = 5
var list: Array<P> = [A(), B()]
public func encode(to encoder: Encoder) throws {
var rootContainer = encoder.container(keyedBy: CodingKeys.self)
try rootContainer.encode(value, forKey: .value)
var listContainer = rootContainer.nestedUnkeyedContainer(forKey: .list)
for p in list {
try listContainer.encode(p)
}
}
enum CodingKeys: String, CodingKey {
case value
case list
}
}
let data = try JSONEncoder().encode(Data())
print(String(data: data, encoding: .utf8)!)
// -> {"value":5,"list":[{"className":"A"},{"className":"B"}]}
検索用 エラーの例
error: type 'any P' cannot conform to 'Encodable'
try rootContainer.encode(list, forKey: .list)
note: only concrete types such as structs, enums and classes can conform to protocols
try rootContainer.encode(list, forKey: .list)
note: requirement from conditional conformance of 'Array<any P>' to 'Encodable'
try rootContainer.encode(list, forKey: .list)