Question

J'essaie d'implémenter une fonctionnalité de chat dans mon application, en utilisant Realm.io comme base de données interne pour stocker les messages de discussion et PubNub pour envoyer et recevoir des messages.J'ai ChatSessions, qui définissent les canaux sur lesquels les messages sont envoyés, et ChatMessages, qui représentent les messages eux-mêmes et contiennent des références au texte du message, la date d'envoi du message, le nom de l'expéditeur du message, et la ChatSession dont le message fait partie.

Dans le code suivant, j'initialise un ChatMessage à partir d'un PNMessage reçu sur le canal, tous les champs étant spécifiés.Le problème que je rencontre est que lorsque Realm va écrire le message dans la base de données, le champ de session de ChatMessage est défini sur zéro, malgré le fait que juste avant l'appel de la méthode d'écriture, le champ de session a une ChatSession valide spécifiée.

- (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];
}

Le NSLog juste après avoir défini chatMessage.session enregistre correctement ce que je veux.Le chatMessage a le nom de session correct.Cependant, le NSLog dans writeToDefaultRealm :enregistre correctement le texte du message, mais enregistre une valeur nulle pour session.sessionName.

Est-ce que quelqu'un sait pourquoi ce champ de session est défini sur zéro ?Merci

MODIFIER

ChatMessage.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)

ChatSession.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)
Était-ce utile?

La solution

Realm ne prend actuellement pas en charge l'attribution à une propriété RLMObject en dehors d'une transaction d'écriture.Alors quand tu le fais chatMessage.session = [matches firstObject];, parce que session est un RLMObject propriété (ChatSession), cela doit être fait dans une transaction d'écriture.Voici une solution possible :

- (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;
    }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top