Using Codable and Realm in swift 4.0 with List\ Type 'News' does not conform to protocol 'Encodable' JSON is like Realm framework version: 3.0.1 Xcode version: Version 9.0.1 (9A1004) iOS/OSX version: iOS 10.0 Is it possible in this way? If not, is there any other way to meet my goal? Thanks~Actual Results
Code Sample
class News: Object, Codable {
var pictureList = List<String>()
private enum CodingKeys: String, CodingKey {
case pictureList
}
public required convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
let pictures = try container.decodeIfPresent([String].self, forKey: .pictureList) ?? [""]
pictureList = List(pictures)
}
}
{
"pictureList": [
"String 1",
"String 2",
"String 3"
]
}
Version of Realm and Tooling
@magic3584 Codable is defined as typealias Codable = Decodable & Encodable, so you should implement encode(to encoder: Encoder) method to conform Codable protocol. Or you can
conform Decodable if you do not need to encode Realm object to another format.
Also, assigning List property doesn't work. List properties should be declared let. So you can only append/remove objects to it/
class News: Object, Decodable {
let pictureList = List<String>()
private enum CodingKeys: String, CodingKey {
case pictureList
}
public required convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
let pictures = try container.decodeIfPresent([String].self, forKey: .pictureList) ?? [""]
pictureList.append(objectsIn: pictures)
}
}
@kishikawakatsumi I added a compute [String] property with only get ,and a String property to save to Realm, but it's a little more ugly, your solution is perfect!
Thanks ~
Is it possible meet the goal without the func init(from decoder: ) throws because I have to write a few codes like property = try container.decodeIfPresent()
@magic3584 Currently, no. Compiler code generation support of Codable protocol works only a class has non-argument initializer (init()). Realm Object cannot be initialized by init().
@kishikawakatsumi I have ask on stackoverflow https://stackoverflow.com/questions/47031302/how-to-conform-to-codable-and-using-realm-in-swift-4-when-class-has-a-array-of-s
So the answer is no?
@magic3584 No. You need to write mapping code in required convenience init(from decoder: Decoder) throws yourself. Compiler code generation doesn't work.
@kishikawakatsumi Got it, thanks~
Most helpful comment
@magic3584
Codableis defined astypealias Codable = Decodable & Encodable, so you should implementencode(to encoder: Encoder)method to conformCodableprotocol. Or you canconform
Decodableif you do not need to encode Realm object to another format.Also, assigning
Listproperty doesn't work.Listproperties should be declaredlet. So you can onlyappend/removeobjects to it/