Search code examples
iosios6uikit-state-preservation

Application state preservation and restoration without using storyboard?


I have added uinavigationcontroller in AppDelegate.m like this

 self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];

UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:self.viewController];
nav.restorationIdentifier = @"nav1";
self.window.rootViewController = nav;

My ViewController.m look like this

- (void)viewDidLoad
{
      [super viewDidLoad];
       self.restorationIdentifier = @"secondViewController";
    // Do any additional setup after loading the view, typically from a nib.
}

-(IBAction)click:(id)sender {

     secondViewController *svc = [[secondViewController  alloc]initWithNibName:@"secondViewController" bundle:nil];
      svc.restorationIdentifier = @"secondViewController";

      svc.restorationClass = [self class];
     [self.navigationController pushViewController:svc animated:YES];
}

My secondViewController.m like

+(UIViewController *)viewControllerWithRestorationIdentifierPath:(NSArray *)identifierComponents coder:(NSCoder *)coder
{
    NSLog(@"viewControllerWithRestorationIdentifierPath");
    UIViewController * myViewController =
    [[secondViewController alloc]
     initWithNibName:@"secondViewController"
     bundle:nil];

    return myViewController;
}

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization

    }
    return self;
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    label.text = @"sdfkheiowodhnskjfdgewluri3y2oejdscndjshfiledhdsfhewilufhyeows";

    // Do any additional setup after loading the view from its nib.
}

-(void)encodeRestorableStateWithCoder:(NSCoder *)coder
{
    NSLog(@"encodeRestorableStateWithCoder");

    [coder encodeObject:label.text forKey:@"UnsavedText"];

    [super encodeRestorableStateWithCoder:coder];
}

-(void)decodeRestorableStateWithCoder:(NSCoder *)coder
{
    NSLog(@"decodeRestorableStateWithCoder");

    [super decodeRestorableStateWithCoder:coder];

    label.text = [coder decodeObjectForKey:@"UnsavedText"];
}

In Output

I get encodeRestorableStateWithCoder but after this when I press home button and then again run application my application state not present secondViewController and decodeRestorableStateWithCoder not get called.

I dont know where I'm doing wrong?


Solution

  • I got it working by adding this in appdelegate.m

    NSString * const kRootViewControllerKey = @"RootViewKey";
    
    - (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(&predicate, ^ {
    
            self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
            // Override point for customization after application launch.
            self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    
            UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:self.viewController];
            nav.restorationIdentifier = @"NavigationController";
            self.window.rootViewController = nav;
            [self.window makeKeyAndVisible];
        });
    }
    
    // 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;
        }
    
    }