Question

Been trying to create a One to Many relationship with core data with little progress.

Just trying to make a simple core data example.

Entity A = Type: typeName = String.

Entity B = Routine: routineName = String.

Relationship: Type has many routines.

Ive got a few view controllers.

  1. TypeViewController (Table view controller to list all the Types from Entity A.

  2. AddTypeViewController (View controller to add a type to the entity through a typeTextField. This is pushed from a add button in the TypeViewController)

  3. RoutineViewController (Table view controller which is pushed when a type is selected from TypeViewController. Lists the routines from Entity B associated with the type selected.

  4. AddRoutineViewController (View controller to add Routine to entity B through routineNameTextField. This is pushed from a add button in the RoutineView Controller.

I started off with implementing just the first Entity and managed to get the First 2 view controllers working. (Was able to add types and view them on the first view controller.

Once i created the second entity and linked the relationship (also the inverse relationship too) the first part stopped working.

Q. Do i have to change the way data is fetched in view controller 1? (As in this view controller i am only fetching data from Entity A).

Q. Is it possible to be adding data separately? (adding type data from the view controller 2. and adding routine data from view controller 4.)

Q. When saving data in view controller 4...

- (IBAction)savePressed:(id)sender {

RoutinePlan *routinePlan = [[RoutinePlan alloc] initWithEntity:[NSEntityDescription entityForName:@"RoutinePlan" inManagedObjectContext:self.managedObjectContext]
                                insertIntoManagedObjectContext:self.managedObjectContext];


[routinePlan setValue:self.rNameTextField.text forKey:@"rName"];


**How to add this routine to the selected type**


NSError *savingError;
if (![self.managedObjectContext save:&savingError])NSLog(@"Error saving: %@", savingError);


}

Thank you for any help. If any more information is needed i can provide it...

Also does anyone know of a basic example out there of one to many relationships?

EDIT:

***Code snippet from TypeViewController.m

- (NSManagedObjectContext *)managedObjectContext{
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)]) {
    context = [delegate managedObjectContext];
}
return context;}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if ([[segue identifier] isEqualToString:@"current Type Selected"]) {
    NSManagedObject *selectedRoutine = [self.routineTypeArray objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
    RoutinePlanViewController *destViewController = segue.destinationViewController;
    destViewController.routineTypeObject = selectedRoutine;
}}
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Type"];
self.routineTypeArray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];
[self.tableView reloadData];}

**Code Snippet from AddTypeViewController.m

- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)]) {
    context = [delegate managedObjectContext];
}
return context;}
- (IBAction)savePressed:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
NSManagedObject *newRoutine = [NSEntityDescription insertNewObjectForEntityForName:@"Type" inManagedObjectContext:context];
[newRoutine setValue:self.rTypeTextField.text forKey:@"rType"];    
NSError *error = nil;
if (![context save:&error]) {
    NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
}
[self dismissViewControllerAnimated:YES completion:nil];    }

**Code Snippet from RoutineViewController.m

@synthesize routineTypeObject;
- (NSManagedObjectContext *)managedObjectContext{
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)]) {
    context = [delegate managedObjectContext];
}
return context;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"current Type Selected"]) {
    AddRoutineViewController *destViewController = segue.destinationViewController;
    destViewController.routineTypeObject = routineTypeObject;
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
// Fetch the devices from persistent data store
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Routine"];
self.routineArray = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];    
[self.tableView reloadData];
}

**Code Snippet from AddRoutineViewController.m

@synthesize routineTypeObject;
- (NSManagedObjectContext *)managedObjectContext {
NSManagedObjectContext *context = nil;
id delegate = [[UIApplication sharedApplication] delegate];
if ([delegate performSelector:@selector(managedObjectContext)]) {
    context = [delegate managedObjectContext];
}
return context;
}
- (IBAction)savePressed:(id)sender {
Routine *routinePlan = [[Routine alloc] initWithEntity:[NSEntityDescription entityForName:@"Routine" inManagedObjectContext:self.managedObjectContext]
                                insertIntoManagedObjectContext:self.managedObjectContext];
[routinePlan setValue:self.rNameTextField.text forKey:@"rName"];

**Error
[Routine.Type = routineTypeObject];

NSError *savingError;
if (![self.managedObjectContext save:&savingError])NSLog(@"Error saving: %@", savingError);
}
Was it helpful?

Solution

Q. Do i have to change the way data is fetched in view controller 1? (As in this view controller i am only fetching data from Entity A).

No, you shouldn't need to (but you've given no information on how you currently do it or what any error is).

Q. Is it possible to be adding data separately? (adding type data from the view controller 2. and adding routine data from view controller 4.)

Yes, as long as you have a reference to the type that is being edited and the managedObjectContext to add to there is no limitation based on the view controller.

Q. When saving data in view controller 4...

You need to add the line that configures the relationship. The easiest way to do that is:

routinePlan.type = type;

(Where routinePlan has the relationship called type and you have the instance to be edited. Using the dot notation also requires that you have the managed object subclass).

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