0
votes

I'm trying to select an object called "selectedPractice" of a Core Data entity called "Practice" on a view controller called SelectorViewController, and then hold on to the results for use in another controller called RegularViewController. Both are UIViewControllers, as my existing app that I'm trying to append core data to doesn't use Tab or NavigationControllers.

I've tried to set the ManagedObjectContexts of the two controllers to be the same as that of AppDelegate in AppDelegate.m using the following code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
SelectorViewController *svc;
    svc.managedObjectContext = self.managedObjectContext;
    svc.fetchedResultsController = self.fetchedResultsController;

    RegularViewController *rvc;
    rvc.managedObjectContext = self.managedObjectContext;
    rvc.fetchedResultsController = self.fetchedResultsController;
        return YES;
}

AppDelegate.m also has a setupFetchedResultsController method here (adapted from Tim Roadley's excellent work):

- (void)setupFetchedResultsController
{
    // 1 - Decide what Entity you want
    NSString *entityName = @"Practice"; // Put your entity name here
    NSLog(@"AppDelegate Setting up a Fetched Results Controller for the Entity named %@", entityName);

    // 2 - Request that Entity
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];

    // 3 - Filter it if you want
    //request.predicate = [NSPredicate predicateWithFormat:@"Practice.name = Blah"];

    // 4 - Sort it if you want
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
                                                                                     ascending:YES
                                                                                      selector:@selector(localizedCaseInsensitiveCompare:)]];

    // 5 - Fetch it
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                        managedObjectContext:self.managedObjectContext
                                                                          sectionNameKeyPath:nil
                                                                                   cacheName:nil];
    [self.fetchedResultsController performFetch:nil];
    NSLog(@"AppDelegate setupFetchedResultsController completed");
}

This runs fine with all the NSLogs displaying. There is then another instantiation of setupFetchedResultsController in SelectorViewController.m here, but it causes a crash with the following log. Is the issue that the FetchedResultsController is reinitiating ?

2012-07-12 20:49:07.652 WhiteHealth[6969:15b03] SelectorViewController sorting entity complete 2012-07-12 20:49:07.653 WhiteHealth[6969:15b03] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'An instance of NSFetchedResultsController requires a non-nil fetchRequest and managedObjectContext'

- (void)performFetch
{
    if (self.fetchedResultsController) {
        if (self.fetchedResultsController.fetchRequest.predicate) {
            if (self.debug) NSLog(@"[%@ %@] fetching %@ with predicate: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName, self.fetchedResultsController.fetchRequest.predicate);
        } else {
            if (self.debug) NSLog(@"[%@ %@] fetching all %@ (i.e., no predicate)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), self.fetchedResultsController.fetchRequest.entityName);
        }
        NSError *error;
        [self.fetchedResultsController performFetch:&error];
        if (error) NSLog(@"[%@ %@] %@ (%@)", NSStringFromClass([self class]), NSStringFromSelector(_cmd), [error localizedDescription], [error localizedFailureReason]);
    } else {
        if (self.debug) NSLog(@"[%@ %@] no NSFetchedResultsController (yet?)", NSStringFromClass([self class]), NSStringFromSelector(_cmd));
    }
    [pickerView reloadAllComponents];
}

- (void)setupFetchedResultsController
{
    // 1 - Decide what Entity you want
    NSString *entityName = @"Practice"; // Put your entity name here
    NSLog(@"SelectorViewController Setting up a Fetched Results Controller for the Entity named %@", entityName);

    // 2 - Request that Entity
    [NSFetchedResultsController deleteCacheWithName:nil]; 
    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:entityName];
    NSLog(@"SelectorViewController requesting entity complete");

    // 3 - Filter it if you want
    //request.predicate = [NSPredicate predicateWithFormat:@"Person.name = Blah"];

    // 4 - Sort it if you want
    request.sortDescriptors = [NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:@"name"
                                                                                     ascending:YES
                                                                                      selector:@selector(localizedCaseInsensitiveCompare:)]];
    NSLog(@"SelectorViewController sorting entity complete");

    // 5 - Fetch it
    self.fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:request
                                                                        managedObjectContext:self.managedObjectContext
                                                                          sectionNameKeyPath:nil
                                                                                   cacheName:nil];
    [self performFetch];

}
1

1 Answers

3
votes
SelectorViewController *svc;
svc.managedObjectContext = self.managedObjectContext;
svc.fetchedResultsController = self.fetchedResultsController;

RegularViewController *rvc;
rvc.managedObjectContext = self.managedObjectContext;
rvc.fetchedResultsController = self.fetchedResultsController;
    return YES;

isn't going to set the managedObjectContexts for you, you not initializing svc and rvc, all you're doing is making objects. If you want to set the managedObject context, go into the viewDidLoad's or just before you run the fetch request, and do this check:

if (self.managedObjectContext == nil) {
    self.managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
}