Instead of using the NSIndexPaths tapped by the user I went with the underlying NSManagedObjects which is a lot safer (in case number or sorting of objects change) and faster (because I do not need the whole fetchRequest and or view).
I subclassed the UINavigationController and did the following.
When pushing a new TableViewController for a level (stored in parentLevel
) I append this to an array in UserDefaults:
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated {
[super pushViewController:viewController animated:animated];
if([viewController isKindOfClass:[LevelTableViewController class]]){
NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
NSManagedObject *obj = [(LevelTableViewController*)viewController parentLevel];
if(obj!=nil){
[array addObject:[[obj objectID].URIRepresentation absoluteString]];
}
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];
}
}
When I pop a viewController I simply remove the last entry from that array:
- (UIViewController *) popViewControllerAnimated:(BOOL)animated{
UIViewController *vc = [super popViewControllerAnimated:animated];
// remove last object
if([vc isKindOfClass:[LevelTableViewController class]]){
NSMutableArray *array = [NSMutableArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
[array removeLastObject];
[[NSUserDefaults standardUserDefaults] setObject:[NSArray arrayWithArray:array] objectForKey:LevelTablesPersistentKey];
}
return vc;
}
I can then use this array when initializing the NavigationController when the app is next started to rebuild the tree:
- (LevelNavigationController*) initWithRootViewController:(LevelTableViewController*)vc {
if(self = [super initWithRootViewController:vc]){
// Recreate structure from UserDefaults
NSArray *array = [NSArray arrayWithArray:[[NSUserDefaults standardUserDefaults] objectForKey:LevelTablesPersistentKey]];
[[NSUserDefaults standardUserDefaults] setObject:nil forKey:LevelTablesPersistentKey]; // set the array to nil -> will be rebuild when pushing viewcontrollers onto navigation stack
NSPersistentStoreCoordinator *persistentStoreCoordinator = ...; // pointer to coordinator
NSManagedObjectContext * managedObjectContext = ...; // pointer to your context
for (NSString *objId in array) {
NSManagedObjectID *mobjId=[persistentStoreCoordinator managedObjectIDForURIRepresentation:[NSURL URLWithString:objId]];
if(mobjId!=nil){
NSManagedObject *obj = nil;
NSError **err = nil;
obj = [managedObjectContext objectWithID:mobjId];
if(err==nil && obj){
if([obj.entity.name isEqualToString:@"Level"]){
// push level
LevelTableViewController *nextLevel = [[LevelTableViewController alloc] initWithStyle:UITableViewStylePlain];
nextLevel.parentLevel = (Level*)obj;
[self pushViewController:nextLevel animated:NO];
[nextLevel release];
}
}
}
}
}
return self;
}