0
votes

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();
    }

}
2
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

2 Answers

1
votes

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?

0
votes

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];
}