How to Easily Duplicate/Copy an Existing Realm Object

How can I properly copy objects from one Realm object to another object

What you want to do is use:

for record in postsDB.objects(PostModel.self) {
if !combinedDB.objects(PostModel.self).filter("postId == \(record.parentId)").isEmpty {
combinedDB.create(PostModel.self, value: record, update: false)
}
}

The create method is inherited from Object. It tells the target to create a new object. Use true if you want it to look to see if there is already a record there, and update it if there is.
PostModel is the Object type, record is what you want copied.

Edit: I added the if statement to provide more context. You didn't show your class definitions, so I was guessing. This is a working example. I ask for a set of records from DatabaseA and copy it to DatabaseB (postsDB to combinedDB).

So if the type of the object you're trying to insert is a List, I'd recommend you define a subclass of Object, and have at least the list you need as a property.

class TagList: Object {
dynamic var tag = ""
var list = List<PostModel>()

override class func primaryKey() -> String? {
return "tag"
}
}

Full working example illustrating: creating new objects, copying all objects to a second list, deleting from second list after copying, adding to first list (which didn't get anything deleted from it.

import Foundation
import RealmSwift

class Letter: Object {
dynamic var letter = "a"
}

class Letters: Object {
var letterList = List<Letter>()
}

class ListExample {
let listRealmStore = try! Realm() // swiftlint:disable:this force_try

func testThis() {
print(Realm.Configuration.defaultConfiguration.fileURL!)
listRealmStore.beginWrite()
addSingleItems() // add 3 objects to the DB

let firstList = Letters()
let allObjects = listRealmStore.objects(Letter.self)
for item in allObjects {
firstList.letterList.append(item)
}

let secondList = Letters()
let itemsToCopy = firstList.letterList
for item in itemsToCopy {
let obj = listRealmStore.create(Letter.self)
obj.letter = item.letter
secondList.letterList.append(obj)
}

let third = Letter()
third.letter = "Z"
listRealmStore.add(third)

firstList.letterList.append(third)
secondList.letterList.removeLast()
do {
try listRealmStore.commitWrite()
} catch let error {
print("couldn't commit db writes: \(error.localizedDescription)")
}

print("list one:\n\(firstList)")
print("list two:\n\(secondList)")
}

func addSingleItems() {

for letter in ["a", "b", "c"] {
let objectToInsert = Letter()
objectToInsert.letter = letter
listRealmStore.add(objectToInsert)
}
}
}

Results in:

list one:
Letters {
letterList = List<Letter> (
[0] Letter {
letter = a;
},
[1] Letter {
letter = b;
},
[2] Letter {
letter = c;
},
[3] Letter {
letter = Z;
}
);
}
list two:
Letters {
letterList = List<Letter> (
[0] Letter {
letter = a;
},
[1] Letter {
letter = b;
}
);
}

How to copy objects from the default local realm to a MongoDB synced realm using Swift?

Update

Found a potential workaround for this issue in "How can I easily duplicate/copy an existing realm object" using Codable with JSONEncoder and JSONDecoder, https://stackoverflow.com/a/65436546/2226315

Found another function in GitHub Gist migrates local realm to a synced realm, however, the code seems already outdated.


Found a GitHub issue raised in 2014 about how to move/copy objects between realms, https://github.com/realm/realm-cocoa/issues/1076. createInRealm:withObject: was suggested in the comment.

However, after digging into the source code only createInRealm:withValue: is available in Objective-C API, https://github.com/realm/realm-cocoa/blob/84179b4e0b54e11f73723c283c4567c565da62f5/Realm/RLMObject.h#L174

In the official guide on "Add Sync to a Local-Only App", there is a section about "Copy Existing Data" which outlines the flow to copy data from a local realm to a synced realm.

Sample Image

Relevant Info

  • Converting local realms to synced realm
  • https://github.com/realm/realm-cocoa/issues/5381

RealmSwift: Detach an object from Realm, including its properties of List type

This is not yet supported natively by Realm, but a requested feature tracked by issue #3381.

For now, you would need to implement your own deep copy constructor. A common strategy is to do that on every model and call the deep copy constructors of related objects. You need to pay attention though that you don't run into cycles.

Deep copy Realm object in Kotlin

can you please provide more context and appropriate information as I do not see and array's in your code statement. Thank you.

EDIT

Because Money is not a data class, you do not have the auto-generated copy() function available, that leaves you with two options:

  1. Create an custom copy() function in the Money class. This could be mundane if there are huge amount of fields in the class.
  2. Use 3rd party libraries, in which case you'll add external dependency to your RealmObject.

What I will suggest is a no brainer: Try to convert your Money.class to a Data class. You will get auto generated functions and idiomatically it will work as RealmObjects should be key-values pairs.

EDIT

You can use GSON library's serialization/deserialization and hack your way to solve your problem (although this is a hacky way but will do its job):

fun clone(): Money {
val stringMoney = Gson().toJson(this, Money::class.java)
return Gson().fromJson<Money>(stringMoney, Money::class.java)
}

usage:

val originalMoney = Money()
val moneyClone = originalMoney.clone()

Proper way of avoiding duplicate object in Realm?

Depending on whether you want to update the existing object with new data or do nothing if it exists already, you have two alternatives.

If you want to do nothing if it already exists, you can use Realm.object(ofType:,forPrimaryKey:).

let existingPerson = realm.object(ofType: Person.self, forPrimaryKey: primaryKey)

if let existingPerson = existingPerson {
// Person already exists, act accordingly
} else {
// Add person
}

If you want to update the object if it exists and add it if it doesn't, you can simply use realm.add(_:,update:).

do {
try realm.write {
realm.add(personObject,update:true)
}
}

RealmList addAll duplicating object with same primary key

A RealmList works just like an ArrayList, so the same item can be there multiple times. If you want to update SomeObject you should just do that directly. The objects RealmList will reflect those changes.

It isn't clear exactly what you are trying to do, so from the given information it is hard to give more advice.

Realm Swift - Duplicate existing nested Objects

Have an unique property for your store. For example an UUID.

dynamic var uuid = UUID().uuidString

Override the primaryKey function for your Store model, and returns the previously created unique property.

override class func primaryKey() -> String? {
return "uuid"
}

It should do the trick.



Related Topics



Leave a reply



Submit