Using Realm, I noticed the app will crash if I try to save an object that its' ID already exists.
This causes my code look like this for every Realm Object
type I want to create:
func fetchOrCreate(...) -> MyClass? {
let existingObject = realm.object(ofType: MyClass.self, forPrimaryKey: MyClass.primaryKeyFor(...))
let object = existingObject ?? MyClass(with: ...)
return object
}
for any creation of an object. This seems like messy boilerplate. Is it really necessary to check for an existing object each time I create a new one?
Your question
Do I really need to check every time I create an object if such object already exists
Maybe? And the answer depends on what the expected outcome is along with how the models are structured. e.g. there has to be a way to determine what determines if an object is "the same" as another object, and that is done be an objects primary key.
I believe what you're looking for is an Upsert. An Upsert either inserts an object if it doesn't exist, or updates an existing object if it does. Upserts require the model to have a primary key.
Suppose there's a Person object
class Person: Object {
@Persisted(primaryKey: true) var _id = 0
@Persisted var name = ""
}
then let's do an upsert
//assume a person with _id 1234 exists, read it in
let aPerson = realm.objects(Person.self).where { $0._id == 1234 }
try! realm.write {
//create a new person object but give it the same _id
let p = Person(value: ["_id": 1234, name: "Jay"]
realm.add(p, update: .modified)
}
Since the new person object has the same _id and we've specified .modified
, Realm assumes it's the same person and updates that persons name to "Jay".
However, if the _id of 1234 didn't already exist, a completely new person object would be created.
Leaving off that .modified
parameter will crash if an object with that _id exists - as mentioned in the question.
You can read more about it here: Upsert an Object