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?
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.