Propriedade Misteriosamente Definir A Zero
-
20-12-2019 - |
Pergunta
Estou tentando implementar um recurso de bate-papo no meu aplicativo, usando Reino.io como um banco de dados interno para armazenar as mensagens de chat, e PubNub para enviar e receber mensagens.Eu tenho ChatSessions, que definem os canais de que as mensagens são enviadas através de e ChatMessages, que representam as mensagens em si, e conter referências para o texto da mensagem, a data em que a mensagem foi enviada, o nome do remetente da mensagem, e a Sessão de que a mensagem é uma parte.
No código a seguir, estou inicializando um ChatMessage a partir de um PNMessage recebido através do canal, com todos os campos especificados.O problema que eu estou tendo é que, quando o Reino vai escrever a mensagem para o banco de dados, o campo de sessão do ChatMessage é definido como nulo, apesar de que o fato de que a direita antes que o método de gravação é chamado, o campo de sessão válido Sessão especificada.
- (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];
}
O NSLog logo após a definição chatMessage.sessão corretamente registra o que eu quero.O chatMessage tem o correto nome da sessão.No entanto, o NSLog dentro writeToDefaultRealm:corretamente registra o texto da mensagem, mas regista um valor nulo para a sessão.sessionName.
Alguém sabe por que esse campo de sessão está a ser definido como nulo?Obrigado
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)
Sessão de conversação.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)
Solução
Reino, que atualmente não suporta a atribuição de um RLMObject propriedade fora de uma gravação de transação.Então, quando você fizer chatMessage.session = [matches firstObject];
, porque session
é um RLMObject
propriedade (ChatSession
), isso deve ser feito em uma gravação de transação.Aqui está uma possível solução:
- (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;
}
}