I am attempting achieve State Restoration in my app. Core Data was included when the application was initially constructed, with all of its code automatically included inside of the AppDelegate.m . There is a one-to-many relationship between State entity and Country entity. The selectedState instance variable is passed to the CountryTableViewController via prepareForeSegue.
The first tableviewController always appears in its original state. Unfortunately, after a Push Segue to my second tableviewController, restoration does not work. All of my tableViewControllers are created inside of StoryBoard. They all have restorationID's assigned from within StoryBoard. The initial configuration is a UINavigationController that is associated with StatesTableViewController. The StateTableViewController uses a Push Segue via another UINavigationController that is associated with CountryTableViewController. All transitions are working fine. Below is some program code, and hope you can give me advise on how to restore the second tableviewController after the Push Segue..
/
/
/
/
AppDelegate.m
-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navigation = (UINavigationController *)self.window.rootViewController;/
CoreListTableViewController *mtvc = (CoreListTableViewController *)navigation.viewControllers[0];/
/
mtvc.managedObjectContext = self.managedObjectContext;/
/
return YES;
}
StatesTableViewController.m
@interface StatesTableViewController ()<UIDataSourceModelAssociation>
@property(nonatomic)NSFetchedResultsController *fetchedResultsController;
@property(nonatomic)State *restoreSelectedState;
@property (nonatomic, strong)CountyTableViewController *countryTVC;
@end
@implementation StatesTableViewController
@synthesize fetchedResultsController = _fetchedResultsController;
/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
State *item = [self.fetchedResultsController objectAtIndexPath:indexPath];
/
cell.textLabel.text = item.name;
cell.detailTextLabel.text = item.electorialVotes;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
/
if ([segue.identifier isEqualToString:@"segueToCounty"])
{
if ([[segue destinationViewController]isKindOfClass:[UINavigationController class]]) {
UINavigationController *navigation = segue.destinationViewController;
CountyTableViewController *countyTVC = (CountyTableViewController *)navigation.topViewController;
/
countyTVC.managedObjectContext = self.managedObjectContext;
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
State *currentState = (State *)[self.fetchedResultsController objectAtIndexPath:indexPath];/
/
countyTVC.selectedState = currentState;/
self.restoreSelectedState = currentState;
}
}
}
#pragma mark - Preserving & Restoring TableView State
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view {
/
if (!idx)
{
NSLog(@"CountyTVC - modelIdentifierForElementAtIndexPath index is NIL");
return nil;
}
County *oneSession = [self.fetchedResultsController objectAtIndexPath:idx];
NSString *identifier = oneSession.name;
self.selectedCity.selectedCounty = oneSession;
return [[oneSession.objectID URIRepresentation] absoluteString];
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view {
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
self.managedObjectContext = delegate.managedObjectContext;
/
if (!identifier)
{
NSLog(@"CountyTVC -indexPathForElementWithModelIdentifier: NOTidentifier = %@",identifier);/
return nil;
}
NSManagedObjectID *objectID = [self.managedObjectContext.persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:identifier]];
if (!objectID) return nil;
/
NSError *error = nil;
County *oneSession = (County *)[self.managedObjectContext existingObjectWithID:objectID error:&error];
self.selectedCity.selectedCounty = oneSession;
if (error) {
NSLog(@"ERROR getting Session object from MOC:\n%@", [error localizedDescription]);
return nil;
}
if (!oneSession)
{
return nil;
}
NSIndexPath *indexPath = [self.fetchedResultsController indexPathForObject:oneSession];
/
[self.tableView reloadData];
return indexPath;
}
/// CountyTableViewController.m
/
#import "AppDelegate.h"
/
#import "CountyTableViewController.h"
#import "State.h"
#import "addCountyViewController.h"
#import "CityTableViewController.h"
@interface CountyTableViewController ()<addCountyDelegate,NSFetchedResultsControllerDelegate,UIDataSourceModelAssociation>
@property(nonatomic,strong)NSFetchedResultsController *fetchedResultsController;
/
@property(nonatomic)CityTableViewController *selectedCity;
/
@end
@implementation CountyTableViewController
@synthesize fetchedResultsController = _fetchedResultsController;
- (void)viewDidLoad {
[super viewDidLoad];
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];
self.navigationController.title = self.selectedState.name;
self.tableView.restorationIdentifier = NSStringFromClass([self class]);
NSError *error;
if (![[self fetchedResultsController] performFetch:&error])
{
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
County *countyObject = [self.fetchedResultsController objectAtIndexPath:indexPath];
/
cell.textLabel.text = countyObject.name;
return cell;
}
#pragma mark - fetchedResultsController for County table
-(NSFetchedResultsController *)fetchedResultsController
{
NSManagedObjectContext *context = self.managedObjectContext;
if (_fetchedResultsController == nil) {
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"County"];
/
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"state = %@", _selectedState];/
NSSortDescriptor *sortByWord = [[NSSortDescriptor alloc] initWithKey:@"name"
ascending:YES];
fetchRequest.sortDescriptors = @[sortByWord];
NSFetchedResultsController *controller = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];/
self.fetchedResultsController = controller;/
self.fetchedResultsController.delegate = self;
}
return _fetchedResultsController;
}
#pragma mark - encodeRestorable and decodeRestorable
-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
[super encodeRestorableStateWithCoder:coder];
NSLog(@"encodeRestorableStateWithCoder from County");
[coder encodeObject:self.navigationController.title forKey:@"navTitle"];
/
}
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
[super decodeRestorableStateWithCoder:coder];
NSLog(@"decodeRestorableStateWithCoder from County");
/
self.navigationController.title = [coder decodeObjectForKey:@"navTitle"];
}
#pragma mark - Preserving & Restoring CountyTableViewController State
#pragma mark - TableView Selection Object Preserved
- (NSString *)modelIdentifierForElementAtIndexPath:(NSIndexPath *)idx inView:(UIView *)view {
/
if (!idx)
{
return nil;
}
County *oneSession = [self.fetchedResultsController objectAtIndexPath:idx];
NSString *identifier = oneSession.name;
self.selectedCity.selectedCounty = oneSession;
return [[oneSession.objectID URIRepresentation] absoluteString];
}
- (NSIndexPath *)indexPathForElementWithModelIdentifier:(NSString *)identifier inView:(UIView *)view {
AppDelegate *delegate = [[UIApplication sharedApplication]delegate];
self.managedObjectContext = delegate.managedObjectContext;
/
if (!identifier)
{
NSLog(@"CountyTVC -indexPathForElementWithModelIdentifier: NOTidentifier = %@",identifier);
return nil;
}
NSLog(@"CountyTVC - indexPathForElementWithModelIdentifier: identifier = %@",identifier);
NSManagedObjectID *objectID = [self.managedObjectContext.persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:identifier]];
if (!objectID) return nil;
/
NSError *error = nil;
County *oneSession = (County *)[self.managedObjectContext existingObjectWithID:objectID error:&error];
self.selectedCity.selectedCounty = oneSession;
if (error) {
NSLog(@"ERROR getting Session object from MOC:\n%@", [error localizedDescription]);
return nil;
}
if (!oneSession)
{
NSLog(@"CountyTVC - indexPathForElementWithModelIdentifier...\ncould not find the State object to restore");
return nil;
}
NSIndexPath *indexPath = [self.fetchedResultsController indexPathForObject:oneSession];
/
[self.tableView reloadData];
return indexPath;
}
Thank you for your help!