2

I am printing the contents of a managed record to a file. I have one main entity, say, MyAppEntity, and several related entities (People, Place, etc).

I am seeing this output from the file:

/Users/david/Library/Application Support/iPhone Simulator/5.1/Applications/C9ACA218-F2D6-4623-8CAF-5FE763D10FC8/Documents/
 MyApp-0001 12.01.25 
 Summary goes here... 
 Nothing here yet. 
 Relationship 'people' on managed object (0x79eaf7f0) <NSManagedObject: 0x79eaf7f0> (entity: MyAppEntity; id: 0x79eae950 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/MyAppEntity/p1> ; data: {
    audioName = 00010125121910;
    audioNo = 0;
    date = nil;
    MyApp = "MyApp-0001 12.01.25";
    interpret = "Nothing here yet.";
    keyword =     (
    );
    order = 0;
    people =     (
        "0x79ee42f0 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PeopleEntity/p1>",
        "0x79ee4300 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PeopleEntity/p2>"
    );
    place =     (
        "0x79ee6970 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PlaceEntity/p2>",
        "0x79ee6960 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PlaceEntity/p1>"
    );
    recurring = 0;
    summary = "Summary goes here...";
    symbol =     (
    );
    type =     (
    );
}) with objects {(
    <NSManagedObject: 0x79ee47e0> (entity: PeopleEntity; id: 0x79ee42f0 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PeopleEntity/p1> ; data: {
    definition = nil;
    name = me;
    order = 0;
    people = "<relationship fault: 0x79ef5ce0 'people'>";
}),
    <NSManagedObject: 0x79ee4a70> (entity: PeopleEntity; id: 0x79ee4300 <x-coredata:/B86C9CA8-EDE4-452C-BA56-FEF50B4F0FF9/PeopleEntity/p2> ; data: {
    definition = nil;
    name = you;
    order = 1;
    people = "<relationship fault: 0x79e60840 'people'>";
})
)} 

I have two questions... First, what do the fault messages mean? and second, how can I retrieve the values for say people.name or place.name..?

I can post the data model diagram, but it basically looks like this:

MyAppEntity: Attributes: Title Date Details Relationships people, place, etc.

PeopleEntity: Attributes: Name Description Order Relationship: people

PlaceEntity: Attributes: Name Description Order Relationship: place

The relationships are many to many. This is because one task can have many people and the same people can work on multiple tasks.


Thanks to Gerry and to Marcus Zarra in another post. I've finally got it.. If it helps others, here is my code:

NSManagedObjectContext *context = [self managedObjectContext];  
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *mainEntity = [NSEntityDescription entityForName:@"MainEntity" inManagedObjectContext:context];

    [fetchRequest setEntity:mains]; 
    NSError *error = nil;   
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];


    NSLog(@"Record Count is: %i", [fetchedObjects count]);

    // THIS ACTUALLY WORKS.....

     for (MainEntity *mains in fetchedObjects) {
     NSLog(@"Main: %@", mains.name);
         NSSet *peopleSet = [mains valueForKey:@"people"];   
         for (id person in peopleSet) {
             NSLog(@"name = %@", [person valueForKey:@"name"]);
         }
         NSSet *keywordSet = [mains valueForKey:@"keyword"];     
         for (id keyWord in keywordSet) {
             NSLog(@"Keyword = %@", [keyWord valueForKey:@"word"]);
         }
         NSSet *placeSet = [mains valueForKey:@"place"];     
         for (id places in placeSet) {
             NSLog(@"Place = %@", [places valueForKey:@"name"]);
         }
         NSSet *symbolSet = [mains valueForKey:@"symbol"];   
         for (id symbols in symbolSet) {
             NSLog(@"Symbol = %@", [symbols valueForKey:@"symbolName"]);
         }
         NSSet *typeSet = [mains valueForKey:@"type"];   
         for (id types in typeSet) {
             NSLog(@"Type = %@", [types valueForKey:@"typeName"]);
         }
     }

    if (!fetchedObjects || error) {
        NSLog(@"[ERROR] COREDATA: Fetch request raised an error - '%@'", [error description]);
        return;
    }
Community
  • 1
  • 1
ICL1901
  • 7,632
  • 14
  • 90
  • 138

1 Answers1

7

Faults are used so that data can be loaded only when it is needed. When you access the relationship, it will be loaded. See the Faulting and Uniquing in the Core Data Programming Guide.

Once you access the to-many relationship, you will have a set. You can enumerate over the set and access the attributes on the individual managed objects. For example (assuming appObject is an instance of MyAppEntity):

for (id person in [appObject valueForKey:@"people"]) {
    NSLog(@"name = %@", [person valueForKey:@"name"]);
}
gerry3
  • 21,420
  • 9
  • 66
  • 74
  • 1
    They really should have chosen a name other tha fault. It causes a lot of confusion (judging by the number of times it comes up here, anyway!) – jrturton Jan 26 '12 at 08:54
  • Thanks Gerry. I have not had my coffee yet, so please be forgiving... I have entered this code: NSManagedObjectContext *context = [self managedObjectContext]; NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; NSEntityDescription *entity = [NSEntityDescription entityForName:@"AppEntity" inManagedObjectContext:context]; [fetchRequest setEntity:entity]; for (id person in entity.people ) { NSLog(@"name = %@", [person valueForKey:@"name"]); } --- but entity.people gives me an error - Property 'people' not found on object of type 'NSEntityDescription *' – ICL1901 Jan 26 '12 at 12:54
  • Thank you very much Gerry. After digesting through my Intel 4004 brain, I understood what you wrote. Thanks very very much... I've posted my final code above.. Let me know if you see problems with it. Again, I'm much obliged. – ICL1901 Jan 27 '12 at 01:18
  • I don't know if I followed the correct procedure asking my question, as there are other similar questions. It did help. – ICL1901 Jan 27 '12 at 01:30
  • Your code looks fine. I forgot to access "people" using `valueForKey:` and I have updated my answer. I almost always generate classes (using mogenerator) for my Core Data entities, so I'm used to always using properties instead of `valueForKey:`. – gerry3 Jan 27 '12 at 20:17
  • Thanks Gerry. I really love having others look at my code. I don't care for things that don't work, and being an indie developer, as many people who can look at my stuff, the better my products will be. Now, I will look into mogenerator.. Again, I really appreciated the help. – ICL1901 Jan 27 '12 at 20:42