Preserving application state across restarts
I've been trying to preserve the state of my iPhone application by serializing my main UITabBarController using [NSKeyedArchiver archiveRootObject:toFile:], but I'm running into difficulties.
First I had a problem with UIImage, since it doesn't implement the NSCoding protocol, but I solved that by making an extension category for UIImage that stores and retrieves the raw image data.
The problem I'm stuck on now is that my view controllers aren't there when I restore from the archive. I have UINavigationControllers in each of my tabs, and when I restore, the UINavigationItems are still there (I can use the Back buttons and so on to change them) but the view controllers are just gone.
I see that UINavigationController's viewControllers property is marked (nonatomic, copy). Does this mean that when you archive a UINavigationController, it doesn't include its stack of view controllers? If so, how can I get around this? I first thought I would override the NSCoding methods for UINavigationController, but this screws up initialization from the NIB file.
I'm a little perturbed that I've been having this much difficulty preserving app state. I figured it was a common enough use case that it would be straightforward to implement. Am I missing something here?
The attributes on a @property have little or nothing to do with archiving behavior (they only describe how getters and setters work).
Also, just because UI classes support NSCoding, doesn't mean that it can be used to reconstruct state. Most of the time, they support NSCoding so that they can be constructed and loaded from a NIB file using Interface Builder. If you think about all the bits of state that you can't set in Interface Builder -- any number of these features may not be supported by the class' implementation of NSCoding.
Normally, people do not use NSCoding to store application state because exactly what constitutes application state is specific to your application.
Saving application state normally involves storing values yourself that would allow you to recreate the state. i.e. store the index of a selected tab or a series of selected indices representing the path walked through a navigation controller.
Why are you trying to archive the whole tab bar controller? Just use NSUserDefaults and save the selected tab index. Then, when you load the app, select the tab index based on the value saved.
I was never able to get this approach to work either. What i eneded with was having my own protocol, and having each viewcontroller to be to save/restore the metadata needed for that view (you don't need to save the image data for example, just the name of the image). Once you have that, its fairly easy to write some generic code to walk the navigation controllers (+stacks) and save/restore the entire set of data. sounds like a lot of work, but was actually pretty easy.