Note that there are some explanatory texts on larger screens.

plurals
  1. POCorrect way to create and restore UIViewControllers during state restoration?
    text
    copied!<p>I'd like to do state restoration in my app that doesn't use story boards. I'm seeing my primary app ViewController instantiated twice during state restoration - how do you ensure that it's only created once?</p> <p>The way I understand the flow, <code>application:willFinishLaunchingWithOptions</code> and a<code>pplication:didFinishLaunchingWithOptions</code> would use a <code>commonInit</code> method which would setup the applications UIWindow and its rootViewController. In my case, the rootViewController is a UINavigationController with a class named 'MyMainViewController' serving as UINavigation's rootViewController.</p> <p>Along side this I'm also handling <code>willEncodeRestorableStateWithCoder</code> and <code>didDecodeRestorableStateWithCoder</code>, respectively. But it seems that by the time I get to my <code>didDecodeRestorableStateWithCoder</code>, I see two separate instances of MyMainViewController created.</p> <p>What's the way to ensure that only one UIViewController is created during restoration?</p> <p>Order of calls during restoration:</p> <ul> <li>Create new instance MyMainViewController (#1) via application:willFinishLaunchingWithOptions:</li> <li>MyMainViewController's viewControllerWithRestorationIdentifierPath:coder invoked and MainViewController is restored (#2)</li> <li>application:didDecodeRestorableStateWithCoder: is called and UINavigationController is decoded and assigned to self.window</li> </ul> <p>Here's what I'm doing in my AppDelegate:</p> <pre><code>NSString * const kRootViewControllerKey = @"RootViewControllerKey"; - (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self commonInitWithOptions:launchOptions]; return YES; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [self commonInitWithOptions:launchOptions]; return YES; } - (void)commonInitWithOptions:(NSDictionary *)launchOptions { static dispatch_once_t predicate; dispatch_once(&amp;predicate, ^ { // While this will be called only once during the lifetype of the app, when the process is killed // and restarted, I wind up with an instance of MyMainViewController created first from here // and then once again, during MyMainViewController's viewControllerWithRestorationIdentifierPath:coder // that's invoked later on. UIViewController *rootViewController = [MyMainViewController alloc] init]; UINavigationController *aNavController = [[UINavigationController alloc] initWithRootViewController:rootViewController]; aNavController.navigationBarHidden = YES; aNavController.restorationIdentifier = NSStringFromClass([aNavController class]); UIWindow *aWindow = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; aWindow.rootViewController = aNavController; aWindow.restorationIdentifier = NSStringFromClass([window class]); self.window = aWindow; }); } // Encode app delegate level state restoration data - (void)application:(UIApplication *)application willEncodeRestorableStateWithCoder:(NSCoder *)coder { [coder encodeObject:self.window.rootViewController forKey:kRootViewControllerKey]; } // Decode app delegate level state restoration data - (void)application:(UIApplication *)application didDecodeRestorableStateWithCoder:(NSCoder *)coder { // Find the preserved root view controller and restore with it UINavigationController *navControlller = [coder decodeObjectForKey:kRootViewControllerKey]; if (navControlller) { self.window.rootViewController = navControlller; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload