Reputation: 2025
I have an application where I tried using UserDefaults
to save a Codable model locally but the problem is that UserDefault
does not store all the values
of the Model and assigns nil
to some of them and at times the proper value
is assigned. So I decided to try an alternative which is realm and I am able to modify my model to work with realm but I have an issue not which is in the process of decoding an Object in an Object using realm. I was able to make it work when dealing with an Array
object with List
but non array
Objects simply failed to map to JSON
below is a sample array that I am dealing with
{
"id": 732,
"name": "Vendor Name",
"logo": ".../thumb/missing.png",
"kitchens":
{
"id": 36,
"name": "Sandwiches"
}
}
model class
class VendorsList : Object, Decodable {
@objc dynamic var id : Int = 0
@objc dynamic var name : String?
@objc dynamic var logo : String?
// Create your Realm List.
var kitchensList = List<VendorKitchens>()
override class func primaryKey() -> String? {
return "id"
}
private enum CodingKeys: String, CodingKey {
case id
case name
case logo
// Set JSON Object Key
case kitchensList = "kitchens"
}
public required convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
self.logo = try container.decode(String.self, forKey: .logo)
// Map your JSON Array response
let kitchens = try container.decodeIfPresent([VendorKitchens].self, forKey: .kitchensList) ?? [VendorKitchens()]
kitchensList.append(objectsIn: kitchens)
}
}
class VendorKitchens : Object, Decodable {
@objc dynamic var id : Int = 0
@objc dynamic var name : String?
override class func primaryKey() -> String? {
return "id"
}
private enum CodingKeys: String, CodingKey {
case id
case name
}
}
this returns
an error
Failed to map data to JSON
Upvotes: 1
Views: 288
Reputation: 346
Here, try this.
class VendorsList : Object, Decodable {
@objc dynamic var id : Int = 0
@objc dynamic var name : String?
@objc dynamic var logo : String?
@objc dynamic var kitchens: VendorKitchens? = nil
override class func primaryKey() -> String? {
return "id"
}
private enum CodingKeys: String, CodingKey {
case id
case name
case logo
case kitchens = "kitchens"
}
public required convenience init(from decoder: Decoder) throws {
self.init()
let container = try decoder.container(keyedBy: CodingKeys.self)
self.id = try container.decode(Int.self, forKey: .id)
self.name = try container.decode(String.self, forKey: .name)
self.logo = try container.decode(String.self, forKey: .logo)
kitchens = try container.decodeIfPresent(VendorKitchens.self, forKey: .kitchensList)
}
}
class VendorKitchens : Object, Decodable {
@objc dynamic var id : Int = 0
@objc dynamic var name : String?
override class func primaryKey() -> String? {
return "id"
}
private enum CodingKeys: String, CodingKey {
case id
case name
}
}
Upvotes: 1