Search code examples
ioscore-datansfetchedresultscontrolleriphonecoredatarecipesdata-persistence

iOS Core Data to-many relationship insert/fetch


In my application I have trip, which has many stops. This has been specified in the .xcdatamodeld file. I can go ahead an manipulate trips in any manner that I want and they all work okay. However, I am running into issues with adding many stops to each trip. It does not seem to persist. Here is the following code. this code is inside of a a detailViewController of a trip, so a specific trip has already been clicked on.

Trip * trip = [self retrieveObjectWithID:_passedObjectId];


    StopOff *newStop = [NSEntityDescription insertNewObjectForEntityForName:@"StopOff" inManagedObjectContext:managedObjectContext];

    [newStop setValue:stopName forKey:@"stopName"];
    [newStop setValue:stopCity forKey:@"stopCity"];
    [newStop setValue:stopDate forKey:@"stopDate"];
    [newStop setValue:stopAddress forKey:@"stopAddress"];
    [newStop setValue:stopState forKey:@"stopState"];
    [newStop setValue:stopTime forKey:@"stopTime"];

    newStop.trip = trip;
    [trip addStopObject:newStop];

    NSLog(@" stop count %i", [trip.stop count]);

Here is what my console spits out the first time i hit a button to run this: CoreData: annotation: to-many relationship fault "stop" for objectID 0x8bb2810 <x-coredata://4CE70783-4729-46E0-B18B-8E325D1020CC/Trip/p20> fulfilled from database. Got 0 rows 2013-11-24 21:19:43.417 Tracker[30633:70b] stop count 1

If I keep hitting the button, stop count increases. If I relaunch the app the stop count goes back down and starts over again, so it seems that it is not persisting.

My question is, how exactly do I insert many stops that correspond to a trip, and once they are inserted and persist, how do I go ahead and get every corresponding stop to that trip.

Here is the code for which retrieves each trip just fine. and managedObjectContext is handled in the parent view controller using NSFetchedResultsController. Please let me know if you need anymore information

- (Trip*)retrieveObjectWithID:(NSManagedObjectID*)theID
{
    NSError *error = nil;
    Trip *theObject = (Trip*)[self.managedObjectContext existingObjectWithID:theID error:&error];
    if (error)
        NSLog (@"Error retrieving object with ID %@: %@", theID, error);
    return theObject;
}

Solution

  • You are not saving your context after applying the changes (new StopOff objects).

    After adding a StopOff, call [managedObjectContext save:&error] and you will persist your new object to the store.

    CoreData does not save automatically, and without a save: being called, you will loose any temporal changes made to the context.

    also, there is no need for [trip addStopObject:newStop]; as CoreData is taking care of that as part of the inverse relationship.