Pregunta

Estoy tratando de implementar una función de chat en mi solicitud, usando Realm.io como una base de datos interna para almacenar los mensajes de chat y PUBNUB para enviar y recibir mensajes. Tengo chatsessions, que definen los canales que se envían mensajes, y los chatmesajes, que representan los mensajes en sí mismos y tienen referencias al texto del mensaje, la fecha en que se envió el mensaje, el nombre del remitente del mensaje y el nombre del remitente del mensaje y La selección de la que el mensaje es parte de.

En el siguiente código, estoy inicializando un chatmessage de un PNMESSAGE recibido en todo el canal, con todos los campos que se están especificando. El problema que estoy teniendo es que cuando Realm va a escribir el mensaje a la base de datos, el campo de la sesión del Chatmessage se establece en NIL, a pesar de ese hecho de que se llame el método de escritura, el campo de la sesión tiene una selección válida.

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

El NSLOG justo después de configurar chatmessage.session registra correctamente lo que quiero. El Chatmessage tiene el nombre de la sesión correcto. Sin embargo, el NSLOG dentro de WriteTodefaultrealm: logra correctamente el texto del mensaje, pero registra un valor NIL para la sesión. Sesión Nombre.

¿Alguien sabe por qué este campo de sesión está siendo establecido en NIL? Gracias

editar

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)

¿Fue útil?

Solución

Realm no admite actualmente la asignación a una propiedad RLMObject fuera de una transacción de escritura.Entonces, cuando lo hace chatMessage.session = [matches firstObject];, porque session es una propiedad RLMObject (ChatSession), esto debe hacerse en una transacción de escritura.Aquí hay una posible solución:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top