Reputation: 19
I have a struct UISectionModel
with only one property section
, which has a protocol UISectionProtocol
for a type, as follows:
struct UISectionModel: Codable {
let section: UISectionProtocol
}
Here is the implementation of the UISectionProtocol
protocol:
protocol UISectionProtocol: Codable {
var identifier: String? { get }
}
As you can see, I need UISectionModel
to conform to the Codable
protocol, but I keep getting an error stating that it does not conform to neither Decodable
or Encodable
, even though the only property's type is already conforming to Codable
. I suspect it has to do with the fact that this type is a protocol, but I can't figure the exact reason that is causing the error to appear or how to fix it.
Would appreciate some insight!
I tried replacing the type of section
with an enum that conforms to UISectionProtocol
:
struct UISectionModel: Codable {
let section: UIDefaultSection
}
enum UIDefaultSection: UISectionProtocol {
case imageSection(section: UIImageSection)
case labelSection(section: UILabelSection)
var identifier: String? {
switch self {
case .imageSection(let section): return section.identifier
case .labelSection(let section): return section.identifier
}
}
}
This made the error go away, but I'm thinking that section
needs to be of any type that conforms to UISectionProtocol
, instead of being limited only to UIDefaultSection
.
Upvotes: 0
Views: 362
Reputation: 60
The issue you experienced is caused by protocols that don't conform to Codable. When you include a UISectionProtocol field in your UISectionModel struct, the compiler cannot guarantee that all conforming types are also Codable. To fix this problem you can make UISectionModel generic and add a type constraint to ensure the section property is also codable. Here is an updated version of your code. I think this may solve your issue.
protocol UISectionProtocol: Codable {
var identifier: String? { get }
}
struct UISectionModel<T: UISectionProtocol>: Codable where T: Codable {
let section: T
}
struct MySection: UISectionProtocol, Codable {
var identifier: String?
}
Upvotes: 1
Reputation: 536026
I think the problem is that you probably believe that saying
protocol UISectionProtocol: Codable
means that UISectionProtocol conforms to Codable. it doesn't. A protocol does not conform to a protocol. You probably want a generic:
struct SectionModel<T: SectionProtocol>: Codable {
let section: T
}
protocol SectionProtocol: Codable {
var identifier: String? { get }
}
(Note that I have stripped the illegal UI prefix off your type names; that prefix belongs to Apple alone.)
Upvotes: 2