Search code examples
iosdatabasecocoacore-datansfetchrequest

Core data relationship returning no value


I have 2 entities with Driver and Work_Shift. Driver has one to many relation with Work_Shift and Work_SHift has one to one relation with Driver.

I am trying to fetch Driver detail while fetching Work_shift data, but i am getting empty values.

Here is my code:

This is the code to fetch Work_Shift detail along with relationship within it.

NSFetchRequest *fetch = [NSFetchRequest fetchRequestWithEntityName:@"Work_Shift"];

    //[fetch setRelationshipKeyPathsForPrefetching:[NSArray arrayWithObject:@"work_shifts.id"]];

    fetch.returnsObjectsAsFaults = NO;

    work_shift_results = [[self managedObjectContext] executeFetchRequest:fetch error:&error];

    if([work_shift_results count]>0)
    {
        Work_Shift *shift = [work_shift_results objectAtIndex:0];
        NSSet *driverSet = shift.work_shifts;
        NSArray *driverArray = [driverSet allObjects];

        NSLog(@"Shift: %@",shift);
    }

This is the output i am getting

<Work_Shift: 0x15678540> (entity: Work_Shift; id: 0x15665460 <x-coredata://7059F32C-63F0-4B2C-A104-5FA339AE2473/Work_Shift/p2> ; data: {
    block = nil;
    "dest_mine_loc_id" = 0;
    "driver_id" = 6;
    "end_date" = nil;
    weight = 0;
    "work_shifts" =     (
    );
})

I have checked and there is are entries in Driver table. I also tried uncommenting the code above, still i get the same result.

The entities are

@class Work_Shift;

@interface Driver : NSManagedObject

@property (nonatomic, retain) NSString * address;
@property (nonatomic, retain) NSString * contact_number;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * is_active;
@property (nonatomic, retain) NSString * name;
@property (nonatomic, retain) Work_Shift *driver;

@end

and

@class Driver;

@interface Work_Shift : NSManagedObject

@property (nonatomic, retain) NSString * block;
@property (nonatomic, retain) NSNumber * dest_mine_loc_id;
@property (nonatomic, retain) NSNumber * driver_id;
@property (nonatomic, retain) NSDate * end_date;
@property (nonatomic, retain) NSNumber * excavator_id;
@property (nonatomic, retain) NSNumber * id;
@property (nonatomic, retain) NSNumber * material_type_id;
@property (nonatomic, retain) NSNumber * mine_location_id;
@property (nonatomic, retain) NSNumber * relative_level_id;
@property (nonatomic, retain) NSNumber * shift_type_id;
@property (nonatomic, retain) NSDate * start_date;
@property (nonatomic, retain) NSNumber * truck_type_id;
@property (nonatomic, retain) NSNumber * weight;
@property (nonatomic, retain) NSSet *work_shifts;
@end

@interface Work_Shift (CoreDataGeneratedAccessors)

- (void)addWork_shiftsObject:(Driver *)value;
- (void)removeWork_shiftsObject:(Driver *)value;
- (void)addWork_shifts:(NSSet *)values;
- (void)removeWork_shifts:(NSSet *)values;

@end

Am i missing something?


Solution

  • Better example as promised

    The model showing the relationships

    enter image description here

    The entity attributes and relationships enter image description here

    enter image description here

    Sample code to create entity and set attributes and relationships. If you want I can email you the sample app.

    - (void)addEntities {
    
        Driver *driver1 = (Driver *)[self createNewDriverMethod1:@"Driver 1" address:@"Address 1"];
        Driver *driver2 = [self createNewDriverMethod2:@"Driver 2" address:@"Address 2"];
    
        Excavator *excavator1 = [self createNewExcavator:@"EXC001" make:@"CAT" model:@"DX1000"];
        Excavator *excavator2 = [self createNewExcavator:@"EXC002" make:@"CAT" model:@"DX2000"];
    
        // Current date as shift start date & time
        NSDate *shiftStartDate = [NSDate date];
    
        Workshift *workshift1 = [self createNewWorkshift:shiftStartDate hours:8.0 driver:driver1];
        workshift1.excavator = excavator1;
    
    
        Workshift *workshift2 = [self createNewWorkshift:shiftStartDate hours:8.0 driver:driver2];
        workshift2.excavator = excavator2;
    
        NSError *error;
    
        if (![[self managedObjectContext] save:&error]) {
            NSLog(@" error saving data %@, %@", error, error.userInfo);
        }
    
        [self listWorkShifts];
    
    
    }
    - (void)listWorkShifts {
    
        NSFetchRequest *req = [[NSFetchRequest alloc] init];
    
        [req setEntity:[NSEntityDescription entityForName:@"Driver" inManagedObjectContext:[self managedObjectContext]]];
    
        NSError *error;
    
        NSArray *result = [[self managedObjectContext] executeFetchRequest:req error:&error];
    
        if (result == nil) {
            NSLog(@" error fetching Driver list %@", error);
            return;
        }
    
        for (Driver *driver in result) {
            NSLog(@" Driver: %@", driver.name);
    
    
            for (Workshift *shift in driver.workshifts) {
    
                NSLog(@"   SHIFT");
                NSLog(@"         Start: %@", [shift.startDate description]); // Get date back as string
                NSLog(@"           End: %@", [shift.endDate description]); // Get date back as string
                NSLog(@"     Excavator: %@, %@", shift.excavator.make, shift.excavator.model);
                NSLog(@"   ");
    
            }
            NSLog(@"   ");
        }
    }
    - (NSManagedObject *)createNewDriverMethod1:(NSString *)name address:(NSString *)address
    {
        NSManagedObject *newDriver = [NSEntityDescription
                                      insertNewObjectForEntityForName:@"Driver"
                                      inManagedObjectContext:[self managedObjectContext]];
    
        [newDriver setValue:name forKey:@"name"];
        [newDriver setValue:address forKey:@"address"];
    
        return newDriver;
    }
    
    - (Driver *)createNewDriverMethod2:(NSString *)name address:(NSString *)address
    {
        Driver *newDriver = [NSEntityDescription
                                   insertNewObjectForEntityForName:@"Driver"
                                   inManagedObjectContext:[self managedObjectContext]];
        newDriver.name = name;
        newDriver.address = address;
        return newDriver;
    }
    - (Workshift *)createNewWorkshift:(NSDate *)startDate hours:(float)hours driver:(Driver *)driver
    {
        Workshift *newWorkshift = [NSEntityDescription
                             insertNewObjectForEntityForName:@"Workshift"
                             inManagedObjectContext:[self managedObjectContext]];
    
        [newWorkshift setValue:startDate forKey:@"startDate"];
    
        // time interval in seconds
        NSTimeInterval interval = hours * 60 * 60;
    
        NSDate *endDate = [startDate dateByAddingTimeInterval:interval];
    
        [newWorkshift setValue:endDate forKey:@"endDate"];
        [newWorkshift setValue:driver forKey:@"driver"];
    
        return newWorkshift;
    }
    - (Excavator *)createNewExcavator:(NSString *)identifier make:(NSString *)make model:(NSString *)model
    {
        Excavator *newExcavator = [NSEntityDescription
                                   insertNewObjectForEntityForName:@"Excavator"
                                   inManagedObjectContext:[self managedObjectContext]];
    
        [newExcavator setValue:identifier forKey:@"identifier"];
        [newExcavator setValue:make forKey:@"make"];
        [newExcavator setValue:model forKey:@"model"];
    
        return newExcavator;
    }