0

I have set up a 1 to many relationship on my core data entities. I am trying to show the detailview copy of the associated data. Currently I have the prepareforseague: method working with the original entity(Routines), however I am at a lose as to how to show the linked entity (RoutinesDetails).

enter image description here

FBCDRoutineViewController

   - (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Routines"];
    self.routines = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

    [self.tableView reloadData];
}  

 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    {
        if ([[segue identifier] isEqualToString:@"UpdateDevice"]) {
            NSManagedObject *selectedDevice = [self.routines objectAtIndex:[[self.tableView indexPathForSelectedRow] row]];
            FBCDRoutineViewController *destViewController = segue.destinationViewController;
            destViewController.routines = selectedDevice;
        }

FBCDRoutineDetailViewController

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

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    // Fetch the devices from persistent data store
    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"RoutinesDetails"];
    self.routines = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

}

- (void)viewDidLoad
{
    [[self navigationController] setNavigationBarHidden:NO animated:YES];

    [super viewDidLoad];
    // Do any additional setup after loading the view.
   if (self.routines) {
     [self.testLabel setText:[self.routines valueForKey:@"routinename"]];
   } 

}

FBCDRoutineDetailViewController

@property (strong) NSManagedObject *routines;

This is my first time with core data and I am looking at how to show the Details entity. Am I Close to getting it working? If not can I get directed at to what I should be looking at.

Any suggestions?

Sgillon
  • 147
  • 12

2 Answers2

0

I think I see several problems--mostly related to the timing of these various calls.

I believe viewDidLoad is called on your detail view before the prepareForSegue is called. So your code in viewDidLoad is trying to display data about your detail item before it has been set.

Then the code in viewDidAppear looks to be overwriting the value you set in prepareForSegue, which doesn't make sense to me (although by this time the view is already displayed and it's not going to affect the label you tried to set in viewDidLoad).

Also, executeFetchRequest: returns an NSArray, not an NSManagedObject, so assigning the result of your fetch to your NSArray property is a BAD idea.

Nicholas Hart
  • 1,734
  • 13
  • 22
  • `prepareForSegue` is called before `viewDidLoad` as far as I know. But you are right that overwriting `self.routines` in `viewWillAppear` does not make sense. – Martin R Jul 09 '13 at 17:16
0

If I understand your problem correctly, you want to display all RoutinesDetails objects that are related to the Routines object passed in prepareForSegue.

Then you would declare two properties in the FBCDRoutineDetailViewController:

@property (strong) NSManagedObject *routines; // the passed object
@property (strong) NSManagedObject *routineDetails; // the displayed details objects

and fetch them like this:

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"RoutinesDetails"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"routineinfo == %@", self.routines];
[fetchRequest setPredicate:predicate];
NSError *error;
self.routineDetails = [managedObjectContext executeFetchRequest:fetchRequest error:&error];

self.routineDetails is now the data source array for the details view.

(Remark: For displaying the result set of a Core Data request in a table view, you might also consider to use a NSFetchedResultsController.)

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
  • so all i need to do now would be set up the table view? Would using a NSfetchedResultscontroller be a better option? – Sgillon Jul 09 '13 at 17:36
  • @user2221799: The advantage of a NSFetchedResultsController is that is has methods to update the table view automatically if objects are inserted, deleted or modified. If you don't need that you can just execute the fetch request and display the `self.routineDetails` array in a table view. – Martin R Jul 09 '13 at 17:38
  • I do think I would prefer to use NSFetchResultsController. Involves a fair bit or rewriting doesn't it? Sorry for all the questions – Sgillon Jul 09 '13 at 17:49
  • @user2221799: It is not really complicated. The NSFetchResultsController and NSFetchResultsControllerDelegate documentation has sample code that you can use as a starting point. If you create a new "Master-Detail Application" in Xcode and activate the "Core Data" checkbox then you will also get code using an FRC. And I am sure that there are good tutorials in the web. - Note however that my answer (how to create the fetch request) applies in any case, you would use the same request for a FRC. – Martin R Jul 09 '13 at 17:55