I have the following objects in my chat app (with one-to-many relationship)
@interface ChatEntry : NSManagedObject
@property (nonatomic, retain) NSString * text;
@property (nonatomic, retain) NSDate * timestamp;
@property (nonatomic, retain) ChatContext *context;
@end
@interface ChatContext : NSManagedObject
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) NSString * userId;
@property (nonatomic, retain) NSSet *entries;
@end
Each conversation (ChatContext) groups all messages send by this user (uniquely identified by userId field).
I’m trying to display a list of conversations which displays the last message of each conversation (similar to iMessage).
I’m using the following code:
NSFetchRequest* request=[[NSFetchRequest alloc] initWithEntityName:@"ChatEntry"];
request.predicate=[NSPredicate predicateWithFormat:@"timestamp=context.entries.@max.timestamp"];
request.sortDescriptors=[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"timestamp" ascending:NO]];
m_chat=[[NSFetchedResultsController alloc] initWithFetchRequest:request managedObjectContext:m_context sectionNameKeyPath:nil cacheName:@"chat"];
m_chat.delegate=self;
This works fine until I receive a new message (with NSFetchedResultsChangeInsert)
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
{
...
}
At that point, I get ANOTHER entry in my table view. The fetch controller keeps the previous entry (even though its timestamp is not the latest one anymore). I’m not sure how to solve this and force the controller to always evaluate the predicate.
Alternatively, I’ve tried to change my query to fetch ChatContext instances, but then I’m not sure how to actually read the latest entry in that context.
OK, I’ve managed to solve that. What I did is to add a “lastMessage” object to the context, which I keep updating on every new message. I then query the list of contexts, sorted by reversed lastMessage.timestamp. New messages update the lastMessage property in their context – which triggers an event and update the UI automatically.