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.
You can make a deep copy of your object via the following extension functions:
import UIKit
import Realm
import RealmSwift
protocol RealmListDetachable {
func detached() -> Self
}
extension List: RealmListDetachable where Element: Object {
func detached() -> List<Element> {
let detached = self.detached
let result = List<Element>()
result.append(objectsIn: detached)
return result
}
}
@objc extension Object {
public func detached() -> Self {
let detached = type(of: self).init()
for property in objectSchema.properties {
guard
property != objectSchema.primaryKeyProperty,
let value = value(forKey: property.name)
else { continue }
if let detachable = value as? Object {
detached.setValue(detachable.detached(), forKey: property.name)
} else if let list = value as? RealmListDetachable {
detached.setValue(list.detached(), forKey: property.name)
} else {
detached.setValue(value, forKey: property.name)
}
}
return detached
}
}
extension Sequence where Iterator.Element: Object {
public var detached: [Element] {
return self.map({ $0.detached() })
}
}
Use
/// in collections
let data = realm.objects(AbcDfg.self).detached
/// single object
data.first?.detached()
We use ObjectMapper to create a deep copy of the object by turning into JSON and then turn that JSON back into same object except it's not associated with Realm.
Mike.