Reputation: 2343
I've got a class which conforms to Decodable protocol (fetching data from API) and I would like to save it in the Realm database. Problem occurs when one of my properties is array (List). It says Cannot automatically synthesize Decodable because List<Item> does not conform to Decodable
What is the best way to bypass this problem? Realm only supports arrays of primitive types.
here is my class:
class PartValue: Object, Decodable {
@objc dynamic var idetifier: Int = 0
let items = List<Item>()
}
Upvotes: 1
Views: 717
Reputation: 3719
Dávid's solution didn't work for me completely. I had to tweak the solution instead by replacing decoder.unkeyedContainer()
to decoder.singleValueContainer()
, below is the solution.
extension List: Decodable where List.Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.singleValueContainer()
let array = try container.decode([Element].self)
self.append(objectsIn: array)
}
}
Upvotes: 1
Reputation: 54716
Using the long awaited conditional conformances implemented in Swift 4.1, you can simply declare List
to conform to Decodable
in case its Element
conforms to Decodable
.
extension List: Decodable where List.Element: Decodable {
public convenience init(from decoder: Decoder) throws {
self.init()
var container = try decoder.unkeyedContainer()
let array = try container.decode(Array<Element>.self)
self.append(objectsIn: array)
}
}
To make this work for your specific case, you need to make sure that Item
also conforms to Decodable
.
If you also need Encodable
conformance, simply extend List
to support that as well.
extension List: Encodable where List.Element: Encodable {
public func encode(to encoder: Encoder) throws {
var container = encoder.unkeyedContainer()
try container.encode(contentsOf: Array(self))
}
}
Upvotes: 2