2014-10-14 3 views
1

У меня довольно простая и простая проблема, которую я пытаюсь решить с помощью Realm. У меня есть объекты, у которых есть свойство массива на них (потоки). Когда я извлекаю все потоки через наш API, они все сохраняются в Realm, поскольку родительские объекты индивидуально сохраняются, и поэтому все дочерние объекты (сообщения & пользователей) в свойстве массива также сохраняются. Но в течение жизненного цикла приложения мне нужно добавить новые сообщения в это свойство массива. Вот что я пытаюсь сделать:Вставить объект в свойство RLMArray на уже сохраненный объект?

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() 
} 

Каждая сообщение имеет свойство, называемое автором, и _id, на которое он жалуется, это _id автора (или пользовательский объект) сообщения. Сообщение об ошибке сложно расшифровать. Я думаю, что это говорит о том, что я пытаюсь создать новый пользовательский объект с первичным ключом, который уже существует. Если это проблема, что я должен сделать вместо этого, чтобы добавить новые объекты Realm к свойству массива на уже сохраненном объекте?

Редактировать

Я устанавливаю первичный ключ для каждой модели, как так:

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

И _id это GUID генерируется MongoDB ... так что это глобально уникальный.

+0

Да, это то, что означает это сообщение. Кажется, что вы фактически не делаете _id ваш первичный ключ (это делается путем переопределения метода класса primaryKey). Также обратите внимание, что первичные ключи должны быть уникальными среди всех объектов определенного подкласса, а не только объектов внутри массива. – Gusutafu

+0

К сожалению, по "user object" вы имели дело с объектами класса User?В этом случае я не думаю, что это точная проблема, она больше похожа на экземпляр соответствующегоThread. – Gusutafu

+0

См. Мои правки о разграничении первичного ключа, уникальности '_id' и строки, где XCode выдает ошибку (на самом деле это не строка, где я' addOrUpdateObject', а где я пытаюсь вставить новое сообщение в свойство массива) –

ответ

0

Ваша проблема, вероятно, в вашем в Message(json:) инициализаторе. Когда вы обрабатываете JSON для сообщения, я предполагаю, что идентификатор автора передается (и, возможно, остальные данные автора). В вашем инициализаторе вы, вероятно, создаете экземпляр нового пользователя, а не получаете экземпляр существующего Пользователя в Царстве. Я воссоздал ваши объекты модели, а затем создал существующего пользователя, поток и сообщение. Я смог десериализовать сообщение от JSON и добавить новое сообщение в существующий массив разговора, если моя логика десериализации захватила существующего пользователя, если бы она была предоставлена. Вот мой пример инициализатора:

init(json : NSDictionary) { 
    self._id = json["_id"] as String 
    self.type = json["type"] as? String ?? "" 
    self.text = json["text"] as? String ?? "" 
    self.created = json["created"] as? NSDate ?? NSDate() 
    self.lastUpdated = json["lastUpdated"] as? NSDate ?? NSDate() 

    if let author = json["author"] as? NSDictionary { 
     if let authorId = author["_id"] as? String { 
      self.author = User(forPrimaryKey: authorId) 
     } 
    } 

    super.init() 
} 

В этом случае, мой пример JSON:

{ 
    "_id": "2", 
    "text": "new message", 
    "author": {"_id": "1"} 
} 

И, наконец, код, который читает JSON и добавляет к уже сохраненной теме:

var error: NSError? 
var jsonDictionary : NSDictionary! 
if let dictionary = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.allZeros, error: &error) as? NSDictionary { 
    jsonDictionary = dictionary 
} else { 
    NSLog("\(error)") 
    return 
} 

let realm = RLMRealm.defaultRealm() 

realm.beginWriteTransaction() 

let newMessage = Message(json: jsonDictionary) 
self.thread.conversation.addObject(newMessage) 
realm.addOrUpdateObject(self.thread) 

realm.commitWriteTransaction() 
1

Проблема заключается в том, что при вызове insertObject ваш объект и все дочерние объекты создаются в Realm вместо обновленных, если они уже существуют. Если вы первый явно обновить объект (который относится ко всем дочерним объектам, а), то это следует избегать вопроса:

var persistedMessage = realm.addOrUpdateObject(embeddedMessage) 
respectiveThread.conversation.insertObject(persistedMessage, atIndex: UInt(0)) 
+0

Такая же ошибка ... ничем не отличается –

Смежные вопросы