Realm-cocoa: Easy way to support copying an existing model object

Created on 11 May 2015  路  6Comments  路  Source: realm/realm-cocoa

based on the discussion: http://stackoverflow.com/questions/30144657/how-can-i-easily-duplicate-copy-an-existing-realm-object

No matter if the model has primary keys or not, there should be an easy way to copy/duplicate an existing model object (and its relationships models).

Most helpful comment

Creating an exact copy of an object with a primary key doesn't make any sense. Creating a copy but with a different primary key can be done with:

let copy = ObjectType(value: oldObject)
copy.primaryKey = newPrimaryKey
realm.add(copy)

which doesn't seem like something that desperately needs one-liner sugar to me.

All 6 comments

Creating an exact copy of an object with a primary key doesn't make any sense. Creating a copy but with a different primary key can be done with:

let copy = ObjectType(value: oldObject)
copy.primaryKey = newPrimaryKey
realm.add(copy)

which doesn't seem like something that desperately needs one-liner sugar to me.

yeah that's what I meant, I didn't want 2 objects with the same primary key, but I will definitely try your code snippet thanks for that, and see if i can generalize because the primary key field is known.

Did you end up generalizing a "copy object with new primary key" functionality, @marcvanolmen? Feel free to reopen this issue if you have any further questions.

@tgoyne doesn't work for me:
Static member 'primaryKey' cannot be used on instance of type 'ObjectType'

@sashakid, If you have a model named User with a primary key named objectId, you use:

let copy = User(value: oldObject)
copy.objectId = newPrimaryKey // maybe `UUID().uuidString`
realm.add(copy)

As of now, Dec 2020, there is not proper solution of this issue. We have many workarounds though.

Here one I have been using, and one with less limitations in my opinion.

  1. Make your Realm Model Object classes conform to codable
class Dog: Object, Codable{
    @objc dynamic var breed:String = "JustAnyDog"
}
  1. Create this helper class
class RealmHelper {
    //Used to expose generic 
    static func DetachedCopy<T:Codable>(of object:T) -> T?{
       do{
           let json = try JSONEncoder().encode(object)
           return try JSONDecoder().decode(T.self, from: json)
       }
       catch let error{
           print(error)
           return nil
       }
    }
}
  1. Call this method whenever you need detached / true deep copy of your Realm Object, like this:
 //Suppose your Realm managed object: let dog:Dog = RealmDBService.shared.getFirstDog()
 guard let detachedDog = RealmHelper.DetachedCopy(of: dog) else{
    print("Could not detach Note")
    return
 }
//Change/mutate object properties as you want
 detachedDog.breed = "rottweiler"

As you can see we are piggy backing on Swift's JSONEncoder and JSONDecoder, using power of Codable, making true deep copy no matter how many nested objects are there under our realm object. Just make sure all your Realm Model Classes conform to Codable.

Though its NOT an ideal solution, but its one of the most effective workaround.

Was this page helpful?
0 / 5 - 0 ratings