Reputation: 382
I have this protocol,
protocol PaginableItem {
var resultType: ResultType { get set }
}
with a single property of an enum type,
enum ResultType: String, Codable {
case photo = "PHOTO"
case baseItem = "BASEITEM"
case new = "NEW"
}
I also have 3 different structs and classes with conforms to PaginableItem
and a class with some PaginableItems
,
final class TimelineModel: Codable {
let stream: String
let participants: String
let header1: PaginableList
let header2: PaginableList
let items: PaginableList
}
final class PaginableList: Codable {
let data: [PaginableItem]
let pagination: Pagination
}
I'm trying to cache TimelineModel
using Swift 4 Codable
, but I'm not sure the best way to do that. Xcode is complaining about PaginableItem
not conforming to Codable
.
It is mandatory to implement init(from decoder: Decoder) throws
and encode(to encoder: Encoder) throws
in ResultType
?
Must PaginableItem
implement Codable
also?
Upvotes: 2
Views: 2305
Reputation: 443
PaginableItem
can't conform to Codable
is because Swift protocols can't conform to themselves.
Source:
Protocol doesn't conform to itself?
Encode/Decode Array of Types conforming to protocol with JSONEncoder
Following the second link above, if you want to encode/decode a PaginableItem
you have to type erase them in an AnyPaginableItem
class/struct and make that conform to Encodable
/Decodable
. I've done it like so:
protocol PaginableItem {
var resultType: ResultType { get set }
}
class AnyPaginableItem: Codable {
var resultType: ResultType
init(resultType: ResultType) {
self.resultType = resultType
}
}
enum ResultType: String, Codable {
case photo = "PHOTO"
case baseItem = "BASEITEM"
case new = "NEW"
}
struct ContainsPaginableItem: Codable {
let paginableItem: AnyPaginableItem
}
let paginableItem = AnyPaginableItem(resultType: .photo)
let itemToEncode = ContainsPaginableItem(paginableItem: paginableItem)
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(itemToEncode)
let jsonString = String(data: jsonData, encoding: .utf8)
This example only encodes the properties that can be declared in PaginableItem
, which I assume is all you need.
If you need to encode ALL of the properties of the type conforming to PaginableItem
there's a longer solution in the second link above that you can adopt.
Upvotes: 4
Reputation: 208
Must PaginableItem implement Codable also?
Absolutely! By making sure PaginableItem conforms to Codable, you maintain overall conformance to Codable for PaginableList.
I notice you had ResultType conform to Codable. However what happens if PaginableItem adds another object which does not - could be the danger.
Upvotes: 0