I have Application
protocol with 2 variables. And I have component
struct that has a variable, which confirms to Application
protocol. I need to save this struct
in disk . So I'm confirming it to Codable
protocol. While doing so I'm getting an error like this ,
"Protocol type 'Application' cannot conform to 'Decodable' because only concrete types can conform to protocols"
Here is my code,
public protocol Application {
var name : String {get}
var ownerName : String {get}
}
public struct component : Codable {
let application : Application
private enum CodingKeys: String, CodingKey {
case application
}
public init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
application = try values.decode(Application.self, forKey: .application)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(application, forKey: .application)
}
}
I'm new to swift so sorry if I'm missing something very obvious. Im not able to fix this and I need some help in right direction. Thank you in advance.
How you address this strongly depends on the problem you're solving.
If you want to store and load exactly these two keys in JSON, then Application should be a struct (as jawadAli notes).
If you mean to store more information, but a given Component is tied to exactly one type of Application, then you want Component to be generic:
public struct Component<App: Application & Codable> : Codable {
let application : App
...
}
Note the addition of & Codable
. If all things that conform to Application should be Codable, then you can make that a requirement of Application
:
public protocol Application: Codable {
var name : String {get}
var ownerName : String {get}
}
It is important to understand that this does not make Application conform to Codable. It means that in order to conform to Application, a type must also conform to Codable. It is never possible to decode an abstract type (i.e. a protocol).
If you mean to store more information, but a given Component doesn't actually know what kind of Application it holds, then this is a more complicated problem (and often over-complicated and should be rethought; if you find you're using a lot of as?
tests, then you should almost certainly redesign). If that's your problem, you should explain a bit more what problem you're solving, and we can discuss how to solve it. (It generally requires some kind of dynamic type registration system, and a JSON format that supports metadata about types. Or you can switch to NSCoder and not use JSON.)