It's my first try to encode and decode data with Swift and Core Data. I'm struggling with encoding and decoding arrays of own data types, all of them follwing a certain protocol.
Here's my struct containing the array of [Instrument], where Instrument is a protocol implemented in three structs, named Tool, Driver, and Adapter:
struct Instruments: Codable { // Telling me: Type 'Instruments' does not confirm to protocol 'Decodable' and 'Encodable'
var instruments: [Instrument]
var categories: [InstrumentCategory]
var instrumentCategories: [String: [Instrument]] {
Dictionary(
grouping: instruments,
by: { $0.category }
)
}
...
}
This is how my Instrument protocol looks like:
protocol Instrument: Codable {
var id: String { get }
var name: String { get set }
var category: String { get set }
var isFavorite: Bool { get set }
var errorMessages: [String]? { get set }
mutating func isValid() -> Bool
}
And this is how one of the structs following this Instrument protocol looks like (Driver and Adapter look pretty similar):
struct Tool: Instrument, Hashable, Codable, Identifiable, Comparable {
let id = UUID().uuidString
var name: String
var category: String
var isFavorite: Bool
var profileType: String
var profileSize: String
var length: String?
var driverCouplingId: Int?
var set: String?
var location: String?
var comment: String?
var errorMessages: [String]?
...
}
Compiler tells me already in Instruments that:
- Type 'Instruments' does not conform to protocol 'Decodable
-- Protocol requires initialized 'init(from:)' with type 'Decodable'
-- Cannot automatically synthesize 'Decodable' because '[Instrument]' does not conform to 'Decodable'
Same for encoding: - Type 'Instruments' does not conform to protocol 'Encodable' -- Protocol requires function 'encode(to:)' with type 'Encodable' -- Cannot automatically synthesize 'Encodable' because '[Instrument]' does not conform to 'Encodable'
If I implement these functions, using the enum CodingKeys: CodingKey for the variables instruments and categories in my Instruments struct, the compiler has problems with the arrays:
enum CodingKeys: CodingKey {
case instruments, categories
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
instruments = try container.decode([Instrument].self, forKey: .instruments) // Compiler error: Value of protocol type 'Instrument' cannot conform to 'Decodable'; only struct/enum/class types can conform to protocols
categories = try container.decode([InstrumentCategory].self, forKey: categories) // Compiler error: Cannot convert value of type '[InstrumentCategory]' to expected argument type 'Instruments.CodingKeys'
}
This is where I get completely stuck.