Question

Here's my problem:

I've got 2 Entities :

  • Session (Date date, String name, NSSet behaviours)

  • Behaviour (String category, String Time, String name, NSManagedobject session).

They are in a one-to-many relationship.

In SessioneViewController, I fetch the Session and the Behaviours:

// This is for the fetch request
@property (nonatomic, ratain) NSArray *sessionArray; 

// Here I create the Session Object

Session *newSession = [NSEntityDescription insertNewObjectForEntityForName:@"Session"    inManagedObjectContext:self.managedObjectContext];
newSession.name = self.lblName.text;
newSession.date = [NSDate date];
self.managedObjectContext save:nil];
// I add the Session into the Array
self.sessionsArray = [self.sessionsArray arrayByAddingObject:newSession];

// Here I create the Behaviour Object:
Comportamento *newBehaviour = [NSEntityDescription   insertNewObjectForEntityForName:@"Behaviour" inManagedObjectContext:self.managedObjectContext];     
newBehaviour.name = cell.textLabel.text;
newBehaviour.category = @"Relationship";
newBehaviour.time = _lblTimer.text;

// Here I say which Session is part of the Behaviour
// --- EDIT ---
// Error Code: newBehaviour.session = [self.sessionsArray objectAtIndex:indexPath.row];
newBehaviour.session = [self.sessionsArray lastObject];

Then I have two view controller classes in which I want to display the Sessions and then when a Session is selected I want the related Behaviours.

// In "ArchiveSessionVC.h":
@property (nonatomic, strong) NSFetchedResultsController *frs;
// In "ArchiveSessionVC.m":

- (void) viwDidLoad
{
   if(![[self frs] performFetch:&e]) {
    NSLog(@"Error %@", e);
    abort();
}


-(NSFetchedResultsController *)frs {
if (_frs != nil) {
    return _frs;
}
   NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
   NSEntityDescription *entity = [NSEntityDescription entityForName:@"Session" inManagedObjectContext:self.managedObjectContext];
   [fetchRequest setEntity:entity];

   NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"date"
                                                               ascending:NO];
   NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
   [fetchRequest setSortDescriptors:sortDescriptors];

   _frs = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:nil];

    return _fetchedResultControllerSessions; 
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
       static NSString *CellIdentifier = @"SessioneCell";

       UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
       if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault  reuseIdentifier:CellIdentifier];
        }

        Sessione *sessione = [self.fetchedResultControllerSessions      objectAtIndexPath:indexPath];
        cell.textLabel.text = sessione.nome;

        return cell;
}

Here is where I push the Second view controller for display the Behaviuors:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
      // Push del ViewController dei comportamenti:

      ArchiveBehaviuorsVC *aBehavioursVC =   [[ArchiveBehaviuorsVC alloc]   initWithNibName:@"ArchiveBehaviuorsVC" bundle:nil];
      aBehavioursVC.sessioneSelezionata = [self.fetchedResultControllerSessions     objectAtIndexPath:indexPath];
      [self.navigationController pushViewController:aBehavioursVC animated:YES];
}

My ArchiveBehaviuorsVC is like this:

 //"ArchiveBehaviuorsVC.h"
 @property (nonatomic, strong) Session *selectedSession;

 -(NSFetchedResultsController *)fetchedResultControllerBehaviours
 {
    if (_fetchedResultControllerBehaviours != nil) {
    return _fetchedResultControllerBehaviours;
    }

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Behaviour" inManagedObjectContext:self.managedObjectContext];
    //NSPredicate *predicate = [NSPredicate predicateWithFormat:@"session == %@",self.sessioneSelezionata];
    [fetchRequest setEntity:entity];
    [fetchRequest setPredicate:predicate];


    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"nome"
                                                               ascending:NO];
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
    [fetchRequest setSortDescriptors:sortDescriptors];

    _fetchedResultControllerBehaviours = [[NSFetchedResultsController alloc]   initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext   sectionNameKeyPath:nil cacheName:nil];


    return _fetchedResultControllerBehaviours;
 }

This is part of the code but it doesn't work. How do I tell the fetchedResultzController to display only the Behaviours associate with the Session?

-- EDIT ---

I found the problem, it wasn't a NSPredicate error, the problem was in this line of code:

// Error Code: newBehaviour.session = [self.sessionsArray objectAtIndex:indexPath.row];

// Right Code:

newBehaviour.session = [self.sessionsArray lastObject];
Was it helpful?

Solution

The predicate

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"session == %@",self.sessioneSelezionata];

looks ok to me. Are you sure you are obtaining the wrong behavior? Did you try to enable SQL debugging?

-com.apple.CoreData.SQLDebug X

where X can be 1,2 or 3. The higher the value the more SQL output.

In addition, when you do a save ALWAYS pass in an error reference.

NSError* error = nil;
[context save:&error];

The above snippet returns a bool value so check it. If NO is returned print the error.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top