ユーザーがタップしたNSIndexPathsを使用する代わりに、基盤となるNSManagedObjectsを使用しました。これは、はるかに安全で(オブジェクトの数や並べ替えが変更された場合)、高速です(fetchRequestやビュー全体が必要ないため)。
UINavigationControllerをサブクラス化し、次のことを行いました。
レベル(に格納されている)の新しいTableViewControllerをプッシュするとき、parentLevel
これを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];
}
}
viewControllerをポップすると、その配列から最後のエントリを削除するだけです。
- (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;
}
次に、アプリを起動してツリーを再構築するときにNavigationControllerを初期化するときに、この配列を使用できます。
- (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;
}