I have this JSON response from my service, which I need to map in order to save it in my Realm database.
{
"Customers": [
{
"ID": 1,
"Name": "Customer 1",
"Contacts": [
{
"ID": 1,
"Name": "Contact A",
},
...
]
},
{
"ID": 2,
"Name": "Customer 2",
"Contacts": [
{
"ID": 1,
"Name": "Contact B",
},
...
]
}
]
}
What important to note is that the Contacts array of each Customer can contain an element with ID 1. Not that surprising, since it is a different contact of another Customer. I know the ID of each Customer is unique.
My question is how I should define my Realm Model classes when I want to define a primary key for the Contacts. I think I need to use the ID of the Customer in some way (like a foreign key), but I cannot figure out how. Here are my models so far.
import RealmSwift
import ObjectMapper
import ObjectMapper_Realm
class Customers: Mappable {
var customers = List<Customer>()
required convenience init?(map: Map) {
self.init()
}
func mapping(map: Map) {
customers <- (map["Customers"], ListTransform<Customer>())
}
}
@objcMembers class Customer: Object, Mappable {
dynamic var id: Int?
dynamic var name: String?
required convenience init?(map: Map){
self.init()
}
override static func primaryKey() -> String? {
return "id"
}
func mapping(map: Map) {
id <- map["ID"]
name <- map["Name"]
}
}
@objcMembers class Contact: Object, Mappable {
dynamic var id = 0
dynamic var name: String?
required convenience init?(map: Map){
self.init()
}
/*override static func primaryKey() -> String? {
return "id"
}*/
func mapping(map: Map) {
id <- map["ID"]
name <- map["Name"]
}
}
When I use the code to override the primary key for the Contact model, I get an error saying that an object with ID 1 is already there. Any help is greatly appreciated.
The bottom line here is that primary keys must be unique.
The Contact Realm object has a primary key but what you're trying to initialize the object with is not a unique key so you can't do that (you can't have multiple contacts with a key of 1).
In other words, the Contact object is initialized with a primary key of 1 but then the next one is also being initialized with a key of 1 etc.
I would suggest letting the Realm objects instantiate their own unique key with
@objc dynamic var contact_id = UUID().uuidString
which is guaranteed to be unique and not use the ID being read in as the primary key.
@objcMembers class Contact: Object, Mappable {
dynamic var contact_id = UUID().uuidString
dynamic var name: String?
override static func primaryKey() -> String? {
return "contact_id"
}
}
Note the whole class is being managed with @objcMembers in the class def.