私はいくつかの関係を持つレルムオブジェクトを持っています、誰もがデータベースに複製を作成するために、コピーメソッドを一般化する良いコードスニペットを持っています。
私の場合、オブジェクトを作成し、永続化したくありませんでした。そのため、segiddins
のソリューションは私には機能しませんでした。
Swift
Swift
でユーザーオブジェクトのクローンを作成するには、次を使用します。
let newUser = User(value: oldUser)
;
新しいユーザーオブジェクトは永続化されません。
主キーがない限り、以下を使用してオブジェクトの浅いコピーを作成できます。
realm.create(ObjectType.self, withValue: existingObject)
同様の問題が発生し、レルムオブジェクトのコピーを取得するための簡単な回避策を見つけました。基本的には、次のように、オブジェクトをNSCopyingプロトコルに準拠させる必要があります。
import RealmSwift
import Realm
import ObjectMapper
class Original: Object, NSCopying{
dynamic var originalId = 0
dynamic var firstName = ""
dynamic var lastName = ""
override static func primaryKey() -> String? {
return "originalId"
}
init(originalId: Int, firstName: String, lastName: String){
super.init()
self.originalId = originalId
self.firstName = firstName
self.lastName = lastName
}
func copy(with zone: NSZone? = nil) -> Any {
let copy = Original(originalId: originalId, firstName: firstName, lastName: lastName)
return copy
}
}
次に、オブジェクトで「copy()」メソッドを呼び出すだけです。
class ViewController: UIViewController {
var original = Original()
override func viewDidLoad() {
super.viewDidLoad()
var myCopy = original.copy()
}
}
コピーを持つことの良いところは、レルム書き込みトランザクションを行わなくてもコピーを変更できることです。ユーザーが一部のデータを編集しているが、まだ保存を押していないか、単に気が変わった場合に便利です。
この問題はまだ生きているので、私は解決策を投稿しますが、それでも改善する必要があります。 Object objOut
を受け取り、自分自身を見てフラットプロパティを埋める、このメソッドの重複を持つObjectクラスの拡張を作成しました。フラットでないプロパティ(ネストされたオブジェクト)が見つかった場合、そのプロパティはスキップされます。
_// Duplicate object with its flat properties
func duplicate(objOut: Object) -> Object {
// Mirror object type
let objectType: Mirror = Mirror(reflecting: self);
// Iterate on object properties
for child in objectType.children {
// Get label
let label = child.label!
// Handler for flat properties, skip complex objects
switch String(describing: type(of: child.value)) {
case "Double", "Int", "Int64", "String":
objOut.setValue(self.value(forKey: label)!, forKey: label)
break
default:
break
}
}
return objOut
}
_
レルムのManagerクラス内には、オブジェクトのコピーを作成するために使用するメソッドcopyFromRealm()
があります。実用的な例を示すために、これは私のAppointmentクラスの構造です。
_Appointment object
- flat properties
- one UpdateInfo object
- flat properties
- one AddressLocation object
- flat properties
- one Address object
- flat properties
- one Coordinates object
- flat properies
- a list of ExtraInfo
- each ExtraInfo object
- flat properties
_
これが私がcopyFromRealm()メソッドを実装した方法です:
_// Creates copy out of realm
func copyFromRealm() -> Appointment {
// Duplicate base object properties
let cpAppointment = self.duplicate(objOut: Appointment()) as! Appointment
// Duplicate UIU object
cpAppointment.uiu = self.uiu?.duplicate(objOut: UpdateInfo()) as? UpdateInfo
// Duplicate AddressLocation object
let cpAddress = self.addressLocation?.address?.duplicate(objOut: Address()) as? Address
let cpCoordinates = self.addressLocation?.coordinates?.duplicate(objOut: Coordinates()) as? Coordinates
cpAppointment.addressLocation = self.addressLocation?.duplicate(objOut: AddressLocation()) as? AddressLocation
cpAppointment.addressLocation?.address = cpAddress
cpAppointment.addressLocation?.coordinates = cpCoordinates
// Duplicate each ExtraInfo
for other in self.others {
cpAppointment.others.append(other.duplicate(objOut: ExtraInfo()) as! ExtraInfo)
}
return cpAppointment
}
_
私は、duplicate()メソッド内でネストされたオブジェクトを操作するための適切で合理的な方法を見つけることができませんでした。再帰を考えましたが、コードの複雑さが増しすぎました。
これは最適ではありませんが機能します。ネストされたオブジェクトも管理する方法が見つかった場合は、この回答を更新します。