Swift & Core Data: Encoding and decoding arrays of own types

Viewed 133

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.

0 Answers
Related