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

그러나 나는 다음과 같은 오류 얻을 때마다 :

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

각각의 자세한 상황 들어

*** Terminating app due to uncaught exception 'RLMException', reason: 'Setting unique property '_id' with existing value '540729b543dd5d1868a42b5d'' 

, 여기 내 영역 모델입니다 메시지에는 작성자라는 속성이 있고 메시지에 대한 작성자 (또는 사용자 개체)의 _id_id입니다. 오류 메시지는 해독하기 어렵습니다. 이미 존재하는 기본 키를 사용하여 새 사용자 개체를 만들려고한다는 것입니다. 그게 문제라면 이미 보존 된 객체의 배열 속성에 새 Realm 객체를 추가하려면 어떻게해야합니까?

내가과 같이 각 모델에 대한 기본 키를 설정하고

편집 :

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

그리고 _id은 ... MongoDB에 의해 생성 된 GUID입니다 그래서 전 세계적으로 고유합니다.

+0

예, 그 메시지의 의미입니다. 비록 당신이 실제로 당신의 프라이 머리 키를 만들고있는 것처럼 보이지는 않는다. (이는 클래스 메쏘드 인 primaryKey를 오버라이드함으로써 이루어진다. 또한 기본 키는 배열 내의 객체뿐만 아니라 특정 하위 클래스의 모든 객체에서 고유해야합니다. – Gusutafu

+0

죄송합니다. "사용자 객체"에 의해 User 클래스의 객체를 참조하고 있었습니까?이 경우 정확한 문제는 아니라고 생각합니다. 각각의 Thread 인스턴스가 될 것 같습니다. – Gusutafu

+0

기본 키, '_id'의 독창성, XCode가 오류를 던지는 행 (실제로는'addOrUpdateObject'가 아닌 행이 아니라 배열 속성에 새 메시지를 삽입하려고 시도하는 행)에 대한 편집 내용을 참조하십시오.) –

답변

0

귀하에 문제가 Message(json:) 초기화에 아마. JSON을 메시지로 처리 할 때 필자는 작성자 ID가 전달되었다고 추측하고 (아마도 작성자 데이터의 나머지 부분) 이니셜 라이저에서 영역에있는 기존 사용자의 인스턴스를 가져 오는 대신 새 사용자를 인스턴스화하는 것이 좋습니다. 모델 개체를 다시 만든 다음 기존 사용자, 스레드 및 메시지를 만들었습니다. JSON에서 메시지를 deserialize하고 기존 대화 배열에 새 메시지를 추가 할 수있었습니다. 단, deserialization 로직이 제공되면 기존 사용자를 확보해야합니다. 내 예를 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() 
} 

: : 여기 내 예 이니셜이다

{ 
    "_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

을 호출 할 때 오브젝트와 모든 하위 오브젝트가 이미 존재하는 경우 갱신되지 않고 영역에 작성되는 문제점이 있습니다. 먼저 명시 적으로 (모든 자식뿐만 아니라 객체에 적용되는) 개체를 업데이트하는 경우,이 문제를 피해야한다 :

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

같은 오류 ... 다르지 않다. –