Realm で解決しようとしている、かなり単純でわかりやすい問題があります。配列プロパティを持つオブジェクト (スレッド) があります。API を介してすべてのスレッドをフェッチすると、親オブジェクトが個別に保存され、配列プロパティ内のすべての子オブジェクト (メッセージとユーザー) も適切に永続化されるため、それらはすべて Realm に永続化されます。しかし、アプリのライフサイクル中に、その配列プロパティに新しいメッセージを追加する必要があります。これが私がやろうとしていることです:
func addPubNubMessageToThread(notification: NSNotification) {
if let info = notification.userInfo as? Dictionary<String, AnyObject> {
var embeddedMessage = Message(json: (info["data"] as? NSDictionary)!)
let threadId = (info["thread"]! as String)
// Persist the message to Realm for future use
var respectiveThread = Thread(forPrimaryKey: threadId)
let realm = RLMRealm.defaultRealm()
realm.beginWriteTransaction()
respectiveThread.conversation.insertObject(embeddedMessage, atIndex: UInt(0)) // Always fails here in XCode with the error below
realm.addOrUpdateObject(respectiveThread)
realm.commitWriteTransaction()
}
}
しかし、毎回次のエラーが発生します。
*** Terminating app due to uncaught exception 'RLMException', reason: 'Setting unique property '_id' with existing value '540729b543dd5d1868a42b5d''
詳細なコンテキストについては、ここに私の Realm モデルを示します。
class Message: RLMObject {
dynamic var _id = ""
dynamic var type = ""
dynamic var text = ""
dynamic var author = User()
dynamic var created = NSDate()
dynamic var lastUpdated = NSDate()
}
class Thread: RLMObject {
dynamic var _id = ""
dynamic var name = ""
dynamic var conversation = RLMArray(objectClassName: Message.className())
dynamic var participants = RLMArray(objectClassName: User.className())
dynamic var created = NSDate()
dynamic var lastUpdated = NSDate()
}
class User: RLMObject {
dynamic var _id = ""
dynamic var name = ""
dynamic var firstName = ""
dynamic var lastName = ""
dynamic var email = ""
dynamic var phone = ""
dynamic var username = ""
dynamic var avatar = NSData()
dynamic var created = NSDate()
dynamic var lastUpdated = NSDate()
}
各メッセージには author と呼ばれるプロパティがあり、メッセージの作成者 (またはユーザー オブジェクト)_id
について不平を言っています。_id
エラー メッセージがわかりにくい。すでに存在する主キーを使用して新しいユーザー オブジェクトを作成しようとしていると言っていると思います。それが問題である場合、新しい Realm オブジェクトを既に永続化されたオブジェクトの配列プロパティに追加するにはどうすればよいですか?
編集
次のように、各モデルの主キーを設定しています。
override class func primaryKey() -> String {
return "_id"
}
また_id
、MongoDB によって生成された GUID です...したがって、グローバルに一意です。