I'm a weekend warrior when it comes to programming, so I have probably done something wrong...
I have a split view controller, core data, nsfetchedResultsController, all that works great. I now have an option for the user to create a backup file of the persistentStore.sqlite file. When the user restores from a backup file, the tableview doesn't reflect any change. And on top of that, can't make any lasting changes from then on from the tableview add/delete. When I quit the app and restart it, all the data is there from the back up and all is working well.
How can I force the tableview to get the now new info from the fetched results controller? Or how do I force the
Here's some scatterings of what I have tried so far without success:
MasterViewController.m
- (void)viewDidLoad
{
context = [[OSCDStackManager sharedManager] managedObjectContext];
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(reloadFetchedResults) name:OSFilesUpdatedNotification object:nil];
- (void)reloadFetchedResults:(NSNotification*)note {
NSError *error = nil;
if (![[self fetchedResultsController] performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
if (note) {
[self.tableView reloadData];
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
[self.tableView endUpdates];
[self.tableView reloadData];
}
from a manual refresh pulldown on the tableview...
-(void) updateTable{
context = [[OSCDStackManager sharedManager] managedObjectContext];
NSError *error = nil;
[self.fetchedResultsController performFetch:&error];
//[self.tableView endUpdates];
[self.tableView reloadData];
[self.refreshControl endRefreshing];
}
- (void)viewWillAppear:(BOOL)animated {
[self.tableView reloadData];
}
- (NSFetchedResultsController *)fetchedResultsController
{
context = [[OSCDStackManager sharedManager] managedObjectContext];
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];
//[NSFetchedResultsController deleteCacheWithName:@"cache"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
Even though this is an app for my neighbor, I'd hate tell him to kill and restart the app after a back up...
Solution ended up being a combination of both answers below,
- (void)reloadFetchedResults{
self.fetchedResultsController = nil;
[NSFetchedResultsController deleteCacheWithName:@"cache"];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self.tableView reloadData];
}
Did you delete the cache?
You need to first set the cache name to the fetchedResultsController
(notice the cacheName
argument at the end):
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:query
managedObjectContext:context
sectionNameKeyPath:nil
cacheName:@"CACHE_NAME"];
Then delete the cache when you make an update:
[NSFetchedResultsController deleteCacheWithName:@"CACHE_NAME"];
After doing this, load from core data again by doing this:
NSError *error;
if (![self.fetchedResultsController performFetch:&error]) {
// Update to handle the error appropriately.
NSLog(@"Unresolved error loading data %@, %@", error, [error userInfo]);
exit(-1); // Fail
}
[self.tableView reloadData];
nil out your FRC
-(void)reloadData
{
NSError *error = nil;
self.fetchedResultsController = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
}
else
[self.tableView reloadData];
}
** EDIT ** in case it's not obvious with the 'self' at the front you'll need somewhere in your class
-(NSFetchedResultsController *)fetchedResultsController
{
if (!_fetchedResultsController)
{
_fetchedResultsController = [NSFetchedResultsController alloc]initWithFetchRequest:aFetchRequest
managedObjectContext:aManagedObjectContext // the main thread MOC
sectionNameKeyPath:nil cacheName:nil];
// addional FRC setup etc.
}
return _fetchedResultsController;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With