I have the Animal protocol with 2 structs that conform to it and a Farm struct which stores a list of Animals. Then, I make them all conform to Codable to store it in a file, but it throws the error cannot automatically synthesize 'Encodable' because '[Animal]' does not conform to 'Encodable'
I understand why this happens, but I cannot find a good solution. How can I make the array only accept Codable and Animal, without Animal being marked Codable so this issue does not happen, something like var animals = [Codable & Animal]? (or any other work arounds). Thank you
protocol Animal: Codable {
var name: String { get set }
var sound: String { get set }
}
struct Cow: Animal {
var name = "Cow"
var sound = "Moo!"
}
struct Duck: Animal {
var name = "Duck"
var sound = "Quack!"
}
struct Farm: Codable {
var name = "Manor Farm"
// this is where the error is shown
var animals = [Animal]()
}
--edit-- When I change them to a class, it looks like this:
class Animal: Codable {
var name = ""
var sound = ""
}
class Duck: Animal {
var beakLength: Int
init(beakLength: Int) {
self.beakLength = beakLength
super.init()
name = "Duck"
sound = "Quack!"
}
required init(from decoder: Decoder) throws {
// works, but now I am required to manually do this?
fatalError("init(from:) has not been implemented")
}
}
It would work if I had no additional properties, but once I add one I am required to introduce an initializer, and then that requires I include the init from decoder initializer which removes the automatic conversion Codable provides. So, either I manually do it for every class I extend, or I can force cast the variable (like var beakLength: Int!) to remove the requirements for the initializers. But is there any other way? This seems like a simple issue but the work around for it makes it very messy which I don't like. Also, when I save/load from a file using this method, it seems that the data is not being saved