I see this is a pretty old question.
I have an app that has to implement pretty complicated logic on app launch to determine what UI to show to the user, but also supports state restoration. So without going into all the things my app has to do, I'll just explain what I discovered.
What I noticed is, when I create my UIWindow programmatically in my AppDelgate, the state restoration system creates the view controllers to restore from the last launch (-application:didDecodeRestorableStateWithCoder: is called) but then all the view controllers *immediately dealloc*. The system doesn't install the view controller's on the app delegate's window if it is created programmatically. The state restoration code isn't robust enough to handle this. If the window is created automatically by using a "Main Interface" (storyboard file) the state restoration view controllers do get added the AppDelegate's window automatically, but only if UIKit makes the window.
My AppDelegate instantiates the window the first time the getter is called:
Code Block -(UIWindow*)window |
{ |
if (_window == nil) |
{ |
CGRect bounds = [UIScreen mainScreen].bounds; |
_window = [[UIWindow alloc]initWithFrame:bounds]; |
} |
return _window; |
} |
Anyway, the the state restoration system doesn't call the window getter on my app delegate, and it just makes view controllers that aren't retained by anything and throws them away.
Only solution I was able to come with is to manually restore the root view controller in the app delegate via -application:viewControllerWithRestorationIdentifierPath:coder:
Code Block -(UIViewController*)application:(UIApplication*)application |
viewControllerWithRestorationIdentifierPath:(NSArray<NSString*>*)identifierComponents |
coder:(NSCoder*)coder |
{ |
if ([identifierComponents.lastObject isEqualToString:@"RootVCIDHere"]) |
{ |
UIStoryboard *storyboard = [coder decodeObjectForKey:UIStateRestorationViewControllerStoryboardKey]; |
UIViewController *rootRestoredVC = [storyboard instantiateInitialViewController]; |
self.window.rootViewController = rootRestoredVC; // <-- ADD it to the window manually so the view controllers don't just dealloc right after being created! |
return rootRestoredVC; |
} |
|
return nil; |
} |