I am building some messaging feature. Assuming I have defined a message entity in Core Data with properties "senderId", "receiverId" and "time".
I want to create a NSFetchRequest which returns the latest message send for each pair of users.
The idea is to use a NSPredicate. This what I have at the moment:
NSPredicate *pred = [NSPredicate predicateWithFormat:@"(receiverId = %@ && senderId = ?) || (senderId = %@ && receiverId = ?)", userId, userId];
[fetchRequest setPredicate:pred];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"time" ascending:NO];
fetchRequest.sortDescriptors = @[descriptor];
"userId" is the current user, which may either be the sender or the receiver.
The current state doesn't work, because I don't know how to "associate" the first case (current user is sender) and the second case (current user is receiver) (marked it with "?")? The other user is not known prior to the request. It just has to be the same user.
By sorting it using the "time" property, I would get the latest first, but also the second latest, and so on. I want to get the last message per pair of users.
I was also thinking about using group by feature in query, but don't have a solution yet.
EDIT #1:
Based on Wilko X's answer, I created the following code:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"ENTITY"];
[fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:@"senderId", @"receiverId", nil]];
[fetchRequest setPropertiesToGroupBy:[NSArray arrayWithObjects:@"senderId", @"receiverId", nil]];
[fetchRequest setReturnsDistinctResults:YES];
[fetchRequest setResultType:NSDictionaryResultType];
NSSortDescriptor *descriptor = [NSSortDescriptor sortDescriptorWithKey:@"time" ascending:NO];
fetchRequest.sortDescriptors = @[descriptor];
self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:nil];
What it does is grouping message entities that have the same senderId and receiverId constellation, but it doesn't group all message entities per pair of users having both user1 (a user may be either the sender or receiver per message entity) and user2 may take the role of a sender and receiver.
I think you can user groupBy to achieve this. You can try something like this:
NSEntityDescription *entity = [NSEntityDescription entityForName:@"TheEntityName" inManagedObjectContext:managedObjectContext];
NSAttributeDescription* receiverIdDesc = [entity.attributesByName objectForKey:@"receiverId"];
NSAttributeDescription* senderIdDesc = [entity.attributesByName objectForKey:@"senderId"];
[theFetchRequest setPropertiesToGroupBy:@[receiverIdDesc, senderIdDesc]];