Codableプロトコルを利用してPropertyListへの書き出しを行う際のクラスの指定方法
SwiftのCodableプロトコルに準拠したクラスとそのサブクラスを作成し、それらが混在した配列をPropertyListで書き出し・読み込みを行いたいのですが、クラスの判別ができないようです。
サンプルとしてAnimalクラスを作成し、サブクラスとしてDogを追加しています。本来であればCatやMonkeyなど複数のサブクラスも作成し、
var animals: [Animal]
animals.append(Dog())
animals.append(Cat())
などと追加してanimasをPropertyListとして保存するのが目的です。
エンコードは
let data = try PropertyListEncoder().encode(animals)
で、デコードは
let animals2 = try PropertyListDecoder().decode([Animal].self, from: data)
としています。[Animal].selfとしているせいなのかanimals2にはDogやCatではなくAnimalが復元されてしまいます。
何か書き方を間違えているのでしょうか?
Playgroundでテストできるサンプルです。
import UIKit
class Animal: Codable {
var legCount: Int
init() {
legCount = 4
}
}
class Dog: Animal {
var name: String = "(NO NAME)"
override init() {
super.init()
}
private enum CodingKeys: String, CodingKey {
case name
}
required init(from decoder: Decoder) throws {
try super.init(from: decoder)
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(String.self, forKey: .name)
}
override func encode(to encoder: Encoder) throws {
try super.encode(to: encoder)
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(name, forKey: .name)
}
}
let dog = Dog()
dog.name = "John"
let animals: [Animal] = [dog]
let data = try PropertyListEncoder().encode(animals)
let animals2 = try PropertyListDecoder().decode([Animal].self, from: data)
let a = animals2.first! as? Dog
print(a?.name)
本来であれば最後にJohnと表示されるべきだと思うのですが、aがnilとなってしまいます。
よろしくお願いいたします。