Reputation: 8020
I've got two RLMObjects
:
class Timeline: RLMObject {
dynamic var entries = RLMArray(objectClassName: Entry.className())
dynamic var id = 0
dynamic var title = ""
dynamic var coverPhoto = ""
dynamic var body = ""
override class func primaryKey() -> String {
return "id"
}
}
class Entry: RLMObject {
dynamic var id :Int = 0
dynamic var timelineID :Int = 0
dynamic var name :String = ""
dynamic var caption :String = ""
dynamic var body :String = ""
dynamic var imageURL :String = ""
override class func primaryKey() -> String {
return "id"
}
}
As you can see there is a To-Many relationship between a Timeline and an Entry. A timeline has many Entries.
the JSON fetch and assignment of my timelines works just fine, they are being fetched and set with:
realm.beginWriteTransaction()
Timeline.createOrUpdateInDefaultRealmWithObject(timelineObject)
realm.commitWriteTransaction()
My problem arises when I'm trying to fetch the entries (which is a separate JSON request/response) for a given timeline and set them.
Fetching and creating them like this works just fine:
realm.beginWriteTransaction()
Entry.createOrUpdateInDefaultRealmWithObject(entryObject)
realm.commitWriteTransaction()
But of course that doesn't associate them with my Timeline object. So then I tried to get my Timeline object and then adding the Entry object to my timeline by doing:
let timelineObject = Timeline(forPrimaryKey: id)
timelineObject.entries.addObject(entryObject)
(inside of a transaction ofc).
This works fine for the initial fetch. But when I try to refetch your data, you get the following RLMException:
'RLMException', reason: 'Can't set primary key property 'id' to existing value 59.'
Am I doing something wrong, or is this a bug? It seems like there should be an instance method on RLMObject that creates or updates a product, like it's class method does?
Solution
As segiddins comment suggests, you add the return from the class method: createOrUpdate... and then add that return to your object (in my case, the timelineObject.entries.addObject(entryReturn)
.
let realm = RLMRealm.defaultRealm()
realm.beginWriteTransaction()
for entry in json["entries"] {
...
//Process and map the JSON
...
let entryReturn = Entry.createOrUpdateInDefaultRealmWithObject(entryObject)
timelineObject.entries.addObject(entryReturn)
}
realm.commitWriteTransaction()
Upvotes: 4
Views: 4265
Reputation: 4120
Try adding the Entry
object that gets returned from the createOrUpdate
call.
Upvotes: 5