Frage

Ich versuche, eine Chat-Funktion in meiner Anwendung zu implementieren, indem ich Folgendes verwende Realm.io als interne Datenbank zum Speichern der Chat-Nachrichten und PubNub zum Senden und Empfangen von Nachrichten.Ich habe ChatSessions, die die Kanäle definieren, über die Nachrichten gesendet werden, und ChatMessages, die die Nachrichten selbst darstellen und Verweise auf den Text der Nachricht, das Datum, an dem die Nachricht gesendet wurde, den Namen des Absenders der Nachricht und die ChatSession enthalten dass die Nachricht ein Teil von ist.

Im folgenden Code initialisiere ich eine ChatMessage von einer über den Kanal empfangenen PNMessage, wobei alle Felder angegeben werden.Das Problem, das ich habe, ist, dass beim Schreiben der Nachricht in die Datenbank durch Realm das Sitzungsfeld der Chatnachricht auf Null gesetzt wird, obwohl kurz vor dem Aufruf der Schreibmethode im Sitzungsfeld eine gültige ChatSitzung angegeben ist.

- (void)createChatMessageFromMessage:(PNMessage *)message
{
    NSDictionary *msgDict = message.message;
    ChatMessage *chatMessage = [[ChatMessage alloc] init];
    chatMessage.text = [msgDict objectForKey:@"text"];
    chatMessage.dateSent = [NSDate dateWithTimeIntervalSinceReferenceDate:[[msgDict objectForKey:@"dateSent"] floatValue]];
    chatMessage.sender = [msgDict objectForKey:@"sender"];
    NSPredicate *sessionPredicate = [NSPredicate predicateWithFormat:@"sessionName = %@", [msgDict objectForKey:@"session"]];
    RLMArray *matches = [ChatSession objectsWithPredicate:sessionPredicate];
    if ([matches count] == 1) {
        chatMessage.session = [matches firstObject];
        NSLog(@"Added chatMessage with session name: %@", chatMessage.session.sessionName);
    } else {
        NSLog(@"Error: ChatSession with name %@ not found in db.", [msgDict objectForKey:@"session"]);
        return;
    }
    [NSThread detachNewThreadSelector:@selector(writeToDefaultRealm:) toTarget:self  withObject:chatMessage];
}

#pragma mark - Saving to Realm

- (void)writeToDefaultRealm:(RLMObject *)object
{
    RLMRealm *defaultRealm = [RLMRealm defaultRealm];
    [defaultRealm beginWriteTransaction];
    [defaultRealm addObject:object];
    if ([object isKindOfClass:[ChatMessage class]]) {
        [((ChatMessage *)object).session.messages addObject:object];
        NSLog(@"Wrtiting message with text: %@ with session name: %@", ((ChatMessage *)object).text, ((ChatMessage *)object).session.sessionName);
    } else {
        NSLog(@"Writing session with name: %@", ((ChatSession *)object).sessionName);
    }
    [defaultRealm commitWriteTransaction];
}

Das NSLog direkt nach dem Einstellen von chatMessage.sitzung protokolliert korrekt, was ich will.Die Chatnachricht hat den richtigen Sitzungsnamen.Das NSLog in writeToDefaultRealm jedoch:protokolliert den Nachrichtentext korrekt, protokolliert jedoch einen Nullwert für die Sitzung.Sitzungsname.

Weiß jemand, warum dieses Sitzungsfeld auf Null gesetzt wird?Danke

BEARBEITEN

Chatnachricht.h

#import <Realm/Realm.h>

@class ChatSession;

@interface ChatMessage : RLMObject
// Add properties here to define the model
@property NSString *text;
@property NSDate *dateSent;
@property NSString *sender;
@property ChatSession *session;

@end

// This protocol enables typed collections. i.e.:
// RLMArray<ChatMessage>
RLM_ARRAY_TYPE(ChatMessage)

ChatSitzung.h

#import "ChatMessage.h"
#import <Realm/Realm.h>

@interface ChatSession : RLMObject

// Add properties here to define the model
@property NSDate *dateOpened;
@property NSDate *dateUpdated;
@property NSString *sessionName;
@property NSString *myAlias;
@property NSString *theirAlias;
@property RLMArray<ChatMessage> *messages;

@end

// This protocol enables typed collections. i.e.:
// RLMArray<ChatSession>
RLM_ARRAY_TYPE(ChatSession)
War es hilfreich?

Lösung

Realm unterstützt derzeit nicht die Zuweisung zu einer RLMObject-Eigenschaft außerhalb einer Schreibtransaktion.Also, wenn du es tust chatMessage.session = [matches firstObject];, da session ist ein RLMObject Eigenschaft (ChatSession), muss dies in einer Schreibtransaktion erfolgen.Hier ist eine mögliche Lösung:

- (void)createChatMessageFromMessage:(PNMessage *)message
{
    NSDictionary *msgDict = message.message;
    ChatMessage *chatMessage = [[ChatMessage alloc] init];
    chatMessage.text = [msgDict objectForKey:@"text"];
    chatMessage.dateSent = [NSDate dateWithTimeIntervalSinceReferenceDate:[[msgDict objectForKey:@"dateSent"] floatValue]];
    chatMessage.sender = [msgDict objectForKey:@"sender"];
    NSPredicate *sessionPredicate = [NSPredicate predicateWithFormat:@"sessionName = %@", [msgDict objectForKey:@"session"]];
    RLMArray *matches = [ChatSession objectsWithPredicate:sessionPredicate];
    if ([matches count] == 1) {
        RLMRealm *defaultRealm = [RLMRealm defaultRealm];
        [defaultRealm beginWriteTransaction];
        chatMessage.session = [matches firstObject];
        [chatMessage.session.messages addObject:chatMessage];
        [defaultRealm addObject:chatMessage];
        [defaultRealm commitWriteTransaction];
        NSLog(@"Added chatMessage with session name: %@", chatMessage.session.sessionName);
    } else {
        NSLog(@"Error: ChatSession with name %@ not found in db.", [msgDict objectForKey:@"session"]);
        return;
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top