Reputation: 709
I am creating a simple word game with a menu screen in which I am displaying all of the user's active matches. I would like to sort this array of matches in order from most recently to least recently active, but the only timestamp property associated with players taking turns is a property of GKTurnBasedParticipant
...GKTurnBasedMatch
has no useful sorting property.
GKTurnBasedMatch
has an array of GKTurnBasedParticipant
objects as a property, so I would certainly be able to come up with some sort of solution, but I can't think of anything that wouldn't be really messy and inefficient. Is there any way something simple like NSPredicate
could be used in a case like this to drill down into each array of participants, look at the latest timestamp and sort all the matches in one go?
Upvotes: 4
Views: 465
Reputation: 3961
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
{
NSString *descriptorKey = @"currentParticipant.lastTurnDate";
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:descriptorKey
ascending:NO];
NSArray *sortedMatches = [matches sortedArrayUsingDescriptors:@[sortDescriptor]];
}];
[GKTurnBasedMatch loadMatchesWithCompletionHandler:^(NSArray *matches, NSError *error)
{
NSString *descriptorKey = @"creationDate";
NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:descriptorKey
ascending:NO];
NSArray *sortedMatches = [matches sortedArrayUsingDescriptors:@[sortDescriptor]];
}];
Upvotes: 0
Reputation: 8399
I don't have an NSPredicate
-based solution, or probably anything as elegant as you had hoped, but I ran into the same issue and wrote my own solution and it wasn't actually that bad.
My solution is for a game that can only have two participants, so modify accordingly, but here is the code I ended up using:
[myGamesArray sortUsingComparator:^NSComparisonResult(CHGame *game1,
CHGame *game2) {
if (YES == [game1 localPlayersTurn] && NO == [game2 localPlayersTurn]) {
return NSOrderedAscending;
} else if (NO == [game1 localPlayersTurn] && YES == [game2 localPlayersTurn]) {
return NSOrderedDescending;
}
NSDate *lm1 = [game1.match lastMove];
NSDate *lm2 = [game2.match lastMove];
if (lm1 != nil && lm2 != nil) {
return [lm1 compare:lm2];
}
return NSOrderedSame;
}];
where CHGame
is a custom class I built for my games (which have a GKTurnBasedMatch
match
property), and the instance method localPlayersTurn
returns a BOOL
indicating whether or not it is the local participant's turn or not.
And then I wrote a lastMove
method in a category on GKTurnBasedMatch
:
- (NSDate *)lastMove {
GKTurnBasedParticipant *localParticipant, *otherParticipant;
NSDate *lastMove;
for (GKTurnBasedParticipant *participant in self.participants) {
if (YES == [participant.playerID isEqualToString:[GKLocalPlayer localPlayer].playerID]) {
localParticipant = participant;
} else {
otherParticipant = participant;
}
}
if (localParticipant == self.currentParticipant) {
lastMove = otherParticipant.lastTurnDate;
} else {
lastMove = localParticipant.lastTurnDate;
}
return lastMove;
}
Again, this only works for two total participants, but would be easy to modify for any number of them.
Hope this helps even though it's not exactly what you asked for.
Upvotes: 3