I recently asked a similar question, but was steered towards an alternative solution, but now I find that I do need this in another area. My app tracks players who participate in tournaments. Each player will check in, then add their matches to the database. Each player can check in on multiple days, so there is a one-many relationship. Each match can have two players and players can have multiple matches, so players and matches are a many-many relationship.
I have three entities: Player, CheckIn, and Match
Player Entity < - >> CheckIn Entity Player Entity << - >> Match Entity
The Player.h:
@class CheckIn, Match;
@interface Player : NSManagedObject
@property (nonatomic, retain) NSDate * birthDay;
@property (nonatomic, retain) NSString * email;
@property (nonatomic, retain) NSString * firstName;
@property (nonatomic, retain) NSString * lastName;
@property (nonatomic, retain) NSString * playerID;
@property (nonatomic, retain) NSString * playerImage;
@property (nonatomic, retain) NSString * playerImageSmall;
@property (nonatomic, retain) NSDate * timeOfLastCheckIn;
@property (nonatomic, retain) NSNumber * isCheckedIn;
@property (nonatomic, retain) NSOrderedSet *playerCheckIns;
@property (nonatomic, retain) NSSet *playerMatches;
@end
@interface Player (CoreDataGeneratedAccessors)
- (void)insertObject:(CheckIn *)value inPlayerCheckInsAtIndex:(NSUInteger)idx;
- (void)removeObjectFromPlayerCheckInsAtIndex:(NSUInteger)idx;
- (void)insertPlayerCheckIns:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removePlayerCheckInsAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInPlayerCheckInsAtIndex:(NSUInteger)idx withObject:(CheckIn *)value;
- (void)replacePlayerCheckInsAtIndexes:(NSIndexSet *)indexes withPlayerCheckIns:(NSArray *)values;
- (void)addPlayerCheckInsObject:(CheckIn *)value;
- (void)removePlayerCheckInsObject:(CheckIn *)value;
- (void)addPlayerCheckIns:(NSOrderedSet *)values;
- (void)removePlayerCheckIns:(NSOrderedSet *)values;
- (void)addPlayerMatchesObject:(Match *)value;
- (void)removePlayerMatchesObject:(Match *)value;
- (void)addPlayerMatches:(NSSet *)values;
- (void)removePlayerMatches:(NSSet *)values;
@end
CheckIn.h:
@class Player;
@interface CheckIn : NSManagedObject
@property (nonatomic, retain) NSNumber * challengeBadge;
@property (nonatomic, retain) NSDate * checkInTime;
@property (nonatomic, retain) NSString * player; //convenience string with player's full name
@property (nonatomic, retain) NSNumber * spiritBadge;
@property (nonatomic, retain) NSNumber * stampsBadge;
@property (nonatomic, retain) NSNumber * triviaBadge;
@property (nonatomic, retain) Player *checkedInPlayer;
@end
Match.h
@class Player;
@interface Match : NSManagedObject
@property (nonatomic, retain) NSString * playerOne; //convenience string with player's full name
@property (nonatomic, retain) NSString * playerTwo; //convenience string with player's full name
@property (nonatomic, retain) NSDate * time;
@property (nonatomic, retain) NSString * winner; //convenience string with player's full name
@property (nonatomic, retain) NSOrderedSet *matchPlayers;
@end
@interface Match (CoreDataGeneratedAccessors)
- (void)insertObject:(Player *)value inMatchPlayersAtIndex:(NSUInteger)idx;
- (void)removeObjectFromMatchPlayersAtIndex:(NSUInteger)idx;
- (void)insertMatchPlayers:(NSArray *)value atIndexes:(NSIndexSet *)indexes;
- (void)removeMatchPlayersAtIndexes:(NSIndexSet *)indexes;
- (void)replaceObjectInMatchPlayersAtIndex:(NSUInteger)idx withObject:(Player *)value;
- (void)replaceMatchPlayersAtIndexes:(NSIndexSet *)indexes withMatchPlayers:(NSArray *)values;
- (void)addMatchPlayersObject:(Player *)value;
- (void)removeMatchPlayersObject:(Player *)value;
- (void)addMatchPlayers:(NSOrderedSet *)values;
- (void)removeMatchPlayers:(NSOrderedSet *)values;
@end
My model's Player entity has these relationships: playerCheckIns to CheckIn with inverse checkedInPlayers playerMatches to Match with inverse matchPlayers (this is ordered and has a max of 2)
The tournament admin user will use a tableview to see all the players. For each player, they will need to see a list of the matches that player was in, and a list of checkins that player has. I want to use a predicate for each that can be applied to my CheckIn tableview and Match tableview respectively. It's not relevant, but I am using the SWTableViewCell to put utility buttons in my custom tableviewcells and have setup manual segues to handle the navigation. The match and checkin view controllers each have an NSPredicate *predicate defined to handle the inbound predicate.
When the admin user selects the match utility button in a player cell, I want to load my match table view, passing a predicate that will filter the view to show only matches where the selected player was involved. This will live in my prepareforsegue method for the appropriate segue identifier.
Here's what I have now for matches in my player tableview's prepareforsegue method:
Player *currentPlayer = [self.fetchedResultsController objectAtIndexPath:[self.tableView indexPathForSelectedRow]];
NSPredicate *pred = [NSPredicate predicateWithFormat:@"SUBQUERY(match, $m, ANY $m.matchPlayers == %@).@count > 0", currentPlayer];
NSLog(@"Setting predicate: %@",pred);
filteredMatchVC.predicate = pred;
My NSLog reveals the predicate was set as:
SUBQUERY(match, $m, ANY $m.matchPlayers == nil).@count > 0
So, the currentPlayer Object is not being captured in the predicate.
The transition to a filtered checkin view would be similar, but I have not tried that yet due to this error...
Any help is greatly appreciated!