0

I am trying to get a test app with core data working, but I am not getting any further at this moment, I hope somebody can help me with this.

I am creating an app to store client and their projects. I am using Core data with a Big Nerd Ranch app as an example. This app uses Core data.

What I want to accomplish is that you can delete a project from a client. Only when I delete a project from a client that has several projects, My program goes into error.

As you can see in the log file at the bottom, after deleting, my method

-(NSArray *)relatedProjects:(Client *)client

does not contain any projects anymore. While in

-(void)removeProject:(Project *)project

the logs shows 2 entries.

I am using a Datastore:

-(NSArray *)relatedProjects:(Client *)client; {
    NSFetchRequest *request = [[NSFetchRequest alloc]init];

    NSEntityDescription *e = [[model entitiesByName] objectForKey:@"Project"];

    [request setEntity:e];

    // Check if client is related to Project
    [request setPredicate: [NSPredicate predicateWithFormat:@"clients = %@", client.objectID]];

    NSSortDescriptor *sd = [NSSortDescriptor sortDescriptorWithKey:@"project"
                                                         ascending:YES];
    [request setSortDescriptors:[NSArray arrayWithObject:sd]];

    NSError *error;
    NSArray *result = [context executeFetchRequest:request error:&error];

    if (!result) {
        [NSException raise:@"Fetch failed"
                    format:@"Reason: %@", [error localizedDescription]];
    }

    relatedProjects = [[NSMutableArray alloc] initWithArray:result];

    for (NSString *p in relatedProjects) {
        NSLog(@"RELATEDPROJECTS %@", p );
    }

    if ([relatedProjects count] == 0) {
        NSLog(@"relatedProjects is empty");
    }


    return relatedProjects;
     }

-

-(void)removeProject:(Project *)project {
    // remove from NSManagedObjectContext
    [context deleteObject:project];

    // remove from allProjects array
    [allProjects removeObjectIdenticalTo:project];

    NSLog(@"relatedprojects in remove %@", relatedProjects);

    // remove from relatedProjects array
    [relatedProjects removeObjectIdenticalTo:project];

    NSLog(@"relatedprojects in AFTER remove %@", relatedProjects);

    NSLog(@"removed project %@", [project project]);

}

and my ViewController

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        BITDataStore *ds = [BITDataStore sharedStore];
        NSArray *selectedProjects = [ds relatedProjects:client];

       /* for (NSString *p in selectedProjects) {
            NSLog(@"selectedProjects %@", p );
                   NSLog(@"IndexPath row %d", [indexPath row]);
        }
        */

        Project *pr = [selectedProjects objectAtIndex:[indexPath row]];
        NSLog(@" te verwijderen project is %@ voor client %@", [pr project], [client name]);

        [ds removeProject:pr];

        // Delete the row from the data source
       [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];   // lijkt dezelfde werking te hebben: [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
      }    }

My Log

2013-12-10 14:11:49.863[37414:70b] relatedprojects in remove (
    "<NSManagedObject: 0x8c83880> (entity: Project; id: 0x8c83260 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p4> ; data: {\n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = 123;\n    tasksProjects = \"<relationship fault: 0x8e71750 'tasksProjects'>\";\n})",
    "<NSManagedObject: 0x8c83ac0> (entity: Project; id: 0x8c83270 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p1> ; data: {\n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = ABC;\n    tasksProjects = \"<relationship fault: 0x8c894f0 'tasksProjects'>\";\n})",
    "<NSManagedObject: 0x8c83b20> (entity: Project; id: 0x8c83280 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p2> ; data: {\n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = XYZ;\n    tasksProjects = \"<relationship fault: 0x8d68f90 'tasksProjects'>\";\n})"
)
2013-12-10 14:11:49.863[37414:70b] relatedprojects in AFTER remove (
    "<NSManagedObject: 0x8c83880> (entity: Project; id: 0x8c83260 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p4> ; data: {\n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = 123;\n    tasksProjects = \"<relationship fault: 0x8e71750 'tasksProjects'>\";\n})",
    "<NSManagedObject: 0x8c83b20> (entity: Project; id: 0x8c83280 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Project/p2> ; data: {\n    clients = \"0x8c75430 <x-coredata://71BDF48B-7B2E-487D-A1E2-013904BB6757/Client/p1>\";\n    orderingValue = nil;\n    project = XYZ;\n    tasksProjects = \"<relationship fault: 0x8d68f90 'tasksProjects'>\";\n})"
)
2013-12-10 14:11:49.864[37414:70b] removed project ABC
2013-12-10 14:11:49.865[37414:70b] related projects is empty
2013-12-10 14:11:49.866[37414:70b] **** client in numberOfRowsInSection is CLIENTX
2013-12-10 14:11:49.866[37414:70b] related projects is empty

My Model as requested: enter image description here

my delete rule: enter image description here enter image description here

Eloy
  • 119
  • 1
  • 9

1 Answers1

1

I'm not sure I understand your goal but...if I delete a client I would like to remove all his projects. So cascade rule for projects is ok. On the contrary, if I delete a project, the client should not be deleted. So, nullify for clients should be better.

Does this work for you? Please, also refer to my previous answer since there is a deep explanation on the argument.

Setting up a parent-child relationship in Core Data

Community
  • 1
  • 1
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
  • YES, that's it! I have been searching for this for days. I was so busy looking at the code I forgot the delete rules. Thank you very much! – Eloy Dec 10 '13 at 14:32