0

I have an iOS app that uses Core Data as well as a tab bar controller. In the first tab, the user can add items that get saved in Core Data. In the second tab, there's other functionality that relies on read-only access to the Core Data store. When I open the app and switch between the tabs, the data looks the same, however, if I then add an item in the first tab, and switch to the second tab, it's not showing i.e. there hasn't been a refresh. In the second tab, I initially had the fetch done in viewDidLoad but I've moved it into viewDidAppear hoping that the fetch would happen everytime I switched to the second tab (and the corresponding view appeared) but I've still got the same problem.

How do I trigger a fetch/refresh when I click on the second tab after having added an item in the first tab interface?

-(void)viewDidAppear:(BOOL)animated
{

    NSError *error = nil;
    if (![self.fetchedResultsController performFetch:&error]) {
        /*
         Replace this implementation with code to handle the error appropriately.

         abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
         */
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }

}
BrainLikeADullPencil
  • 11,313
  • 24
  • 78
  • 134
  • Best guess you need to set up and implement the fetchcontroller delegate methods. It's pretty much boiler plate code you copy straight out of the reference. – David Berry Jun 10 '14 at 15:09

2 Answers2

1

You should listen for the notification NSManagedObjectContextObjectsDidChangeNotification

This notification tells you that there has been changes in your database.

For a good explanation look at this post:

How can I track/observe all changes within a subgraph?

Community
  • 1
  • 1
Shingoo
  • 826
  • 10
  • 26
0

Unless you manually change an aspect of the query, you don't need to manually performFetch: more than just once. If the results of the query would change, you'll get notified through the delegate methods. I'd just keep the call on viewDidLoad, as the view will be loaded lazily at the time the controller shows for the first time, which is, when you open it through the UITabBarController button

If you are manually changing the query in between presentations, give us more context so we can help with a proper implementation of it.

Edit: This is a bare minimum implementation that will reload a table view whenever the results of your query would change. The delegate methods allow for more specific behavior like inserting rows or deleting them without reloading the whole table, you can read enough information to implement this from the headers or in the apple docs but this will get you going.

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self fetch];
}

- (void)fetch
{
    if (!self.resultsController) {
        //Optionally create resultsController lazily here, I didn't see where you created it
    }
    [self.resultsController performFetch:&error];
    //The manual fetch call doesn't trigger delegate calls, so you refresh manually here after the fetch.
    [self.tableView reloadData];
}

#pragma mark - UITableViewDataSource

//..
//Implement the table datasource to pull from the NSFetchedResultsController here.
//..

#pragma mark - NSFetchedResultsControllerDelegate

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    [self.tableView reloadData];
}
Fernando Mazzon
  • 3,562
  • 1
  • 19
  • 21
  • I don't understand your answer. I have a viewDidLoad in the tableViewController in the first tab, as well as a viewDidLoad in the tablViewController in the second tab. Should I perform the fetch in both of those viewDidLoad(s) or just one of them? Anyways, I have the fetch in both of them now (as well as in viewDidAppear) and, as the OP states, the data is not current in the second tab (Note, I'm not changing the query between presentations), so what delegate method needs to be implemented? – BrainLikeADullPencil Jun 10 '14 at 14:58
  • If each controller has their own fetched results controller, each controller calls fetch: on viewDidLoad for their own NSFetchedResultsController. As for the other stuff, give me a min and I'll edit my answer with some examples. – Fernando Mazzon Jun 10 '14 at 15:11