How to preserve iPhone application state before terminating the application? - iphone

I have developed an iPhone application with tab bar and navigation controllers.
It is working fine for now.
Now I want the application to save its state before quitting.
Suppose I have 6 tabs and If an incoming call comes , so after relaunching the app I should see the tab selected that was lastly selected .
I have seen several questions on this topic but I am more confused after seeing them,
can anyone tell me a straight way to do this ?

There is no "one size fits all", exact answer to this question - the implementation of saving application state will depending greatly on the structure of the application so much so that any single solution is unlikely to fit your specific case.
There are some general tips and pointers, however, that should put you on the right road to developing a good state preserving solution:
You will typically want to perform any operations to save state in applicationWillTerminate: in your app delegate or by listening for UIApplicationWillTerminateNotification in other classes.
Look at NSUserDefaults. You can use NSUserDefaults to store key/value pairs (similar to an NSDictionary, though you can only store objects that implement NSCoding in NSUserDefaults) relating to preference or other information. Use NSUserDefaults to store state information. One caveat - you shouldn't use NSUserDefaults for storing large amounts of data, as this will slow down your application's launch time (since the values are loaded on launch).
More specific to your case...if all you want to do is preserve the selected tab between application, you should implement applicationWillTerminate: and use NSUserDefaults to store the selected tab index. Then, in your applicationDidFinishLaunching: implementation, you'll check for the existence of that NSUserDefaults key and set the UITabBarController's selected index to the stored value if it exists.
If you want to be able to restore, for example, the navigation stack of the selected tab as well, then you'll need to store enough information so that the navigation stack can be accurately reconstructed. What information you should store in NSUserDefaults is hard to quantify in a general sense as it is highly specific to the structure of your application and the possible iterations of view controller hierarchy within the navigation stack.
If you need to restore a more general navigation stack, including possibly entered user data that you don't want to be lost when the application is closed (such as if the user is creating a new record of some kind), I would suggest that you shift your focus away from storing the application state at the app delegate level and instead focus on having your view controller classes listen for UIApplicationWillTerminateNotification and do their own specific state saving. You would also have to determine some mechanism for using that information saved per view controller on termination to restore the navigation hierarchy. This is a more complex technique that may not be necessary depending on your needs.
Unfortunately this answer is a bit nebulous, especially for the more general and complex cases, because as I noted there is no general solution for this question since it depends so heavily on your application structure.
Here's an example of using NSUserDefaults: http://robertcarlsen.net/2009/06/19/overly-simplistic-saving-state-in-of-for-iphone-847

Related

What's the best way of building an app to display two lists in a single UITableView (switching between datasets)

I'm relatively new to iOS development and am just wanting a few pointers as to what will be the best way to go about doing this. I am building an app with a tab bar and one of those tabs will be a table view at the top of which is a segmented control with two buttons allowing you to swap between datasets.
The first question I have is:
The data is relatively simple but there are about 6000 records would it be best to use a simple NSDictionary as the data source or should I look into using Core Data. Users of the app will simply be able to select a record to add it to a favourites list, or deselect it.
Secondly:
Should I use two different view controllers and swap them in and out depending on which option is selected or should I use a single view controller and swap the data in that class to populate the table.
I'm a registered Apple Dev so I have access to their examples but often can find them difficult to follow, any pointers to resources/tutorials would be VERY appreciated.
First off, for anything nontrivial always consider Core Data - in your case especially so. A 6000-object dictionary can easily get unwieldy to manage.
As for the view controllers, I believe the canonical thing to do is to use a single table view controller (since you remain on a single UITabBarController tab), but change out its data source, or just change the data returned from that source.
If you need it to look reasonably smooth, you can play with the built-in UITableView animation methods - I believe the AP application changed out its news stories by animating out all the old ones and animating in all the new ones within a single table view, so the effect was of a complete dataset change but without the extra view controller.
Generally I've found the Apple examples and tutorials to be the best available, but there's no substitute for just building apps and playing around with the technologies yourself - if you don't understand an example, try to reimplement it yourself and see what's giving you trouble. If you're truly stuck on something, come back and ask another question!
First question:
If your dataset is fairly simple, I would recommend sticking with an array of dictionaries; or, if order is well-defined, and each row has a meaningful unique key, simply use a dictionary.
There's a complexity tradeoff involved in using a large framework like Core Data, and until you have—for instance—relationships expressed in your object model, I don't think the tradeoff is worth taking.
That said, there are performance issues to take into account when making these kinds of decisions. You have 6,000 records, but is each just a key and a value? That wouldn't be such a big deal. But if you have a number of columns, and sorting is an issue, Core Data's SQLite backend would help you out a great deal.
If the array or dictionary is filled with standard Foundation data types, you'd get serialization for free, since all of them implement NSCoding.
Second question:
Read through Apple's article on the model-view-controller design paradigm. The thing to note about what you're trying to do here is that since you're only looking to vary your data, only your model should be changing.
UITableView is designed to make that easy. It's a view, so it doesn't store its data, but it has a dataSource property which it queries to display information. So when your user switches datasets, simply switch your table view's data source.

iPhone CoreData fetch from delegate?

I've got a program which is working and uses Core Data for storage.
However, I'm not entirely sure if I should be keeping my fetch/update methods exclusively to the app delegate?
One example is for a question within the app. The question has a "left" and a "right" statement.
The delegate currently creates the new QuestionVC and passes in the questionNumber for the question. Then the QuestionVC then does a fetch to get the question object and uses the left and right properties of the object to set the text on the screen.
Should I do this the other way round...
The delegate does a fetch on the question number and then creates the QuestionVC and passes in the question object. The QuestionVC then just has to get the left and right text without having to do a fetch at all.
Any tips, advice welcome.
Thanks
Oliver
Both approaches sound valid, but if you can design your view controller hierarchy in such a way that only one object needs to know about Core Data (i.e. pass the question object to your QuestionVC) then that's probably a simpler design, which is probably better.
I personally wouldn't be doing any fetching in my app delegate, though. My app delegates only set up Core Data (i.e. the managed object context) and pass that to the root view controller. I prefer to keep my app delegates as small as possible. I don't use them as an all-purpose singleton.

Wheres the best place Iphone app to place a Data Model instance and how would you Access it?

I am learning tons on this thing. Reading also, but this is awesome!
Ok.. so long story sort I hope. I'm making a data class to pump out some instances of people that have various attributes. I would like my view controllers to be able to access them (through properties of course.. I think) to manipulate their data.
Where in an iphone app would be the best place to do this, and how would you write the code to message to this object. My current setup would be to have a navigation controller with a firstlevelviewcontroller that created a few secondlevelviewcontroller children instances that would do things like pickers for date of birth, and height, weight, etc.
Could the Navigation Controller make these model objects? Should application delegate? Lets say application delegate does. If so, then how would I put references to these objects from my first and second level view controllers?
Awesome!
**Update for the new millenium. **
I'm reading on core data structures, and though they are awesome, they are above and beyond what I need for this project. what I need is simple, I think..
I want one class that is a data class with a few variables that I can manipulate. I want to manipulate these from two view controllers. I might want more than one data instance, so I don't want a singleton data object. I don't need a persistent store of data.
I would like to know how to step by step have this data class instantiated.. should it be in app delegate? can i do it somewhere else? I dont want it a child of one of the view controllers.. How would I do that? then, how would I reference it from the view controllers and manipulate data (I'm pretty sure through properties but I can't figure out how to reference the instances to make this happen).
CHeers! thanks for the help!
Lots of questions that fringe on conjunction of various best practices.
First, the NSManagedObjectContext (if instantiated in the application delegate) can be shared in any number of ways. You can push it on through as you load your controllers or, something I've been more want to do (and will gladly argue the merits), you can hand it off to a Singleton that any controller has access to.
Depending on the model graph and how your UI maps to the data objects (you didn't say), keep in mind being memory friendly. I defer creating the NSFetchRequests until there is a controller that needs the data (CRUD).
If you want to edit your question or add comments that may provide more clarity... the answer may change
Frank

How can I preserve views and controllers across restart of an application in iPhone?

I am building up a game and want to give user a continue functionality when he restarts the application. So I want to know how to code or what to do to start an application where it left last time.
Is there any sample code available in app center which explains how can this be possible.
Tnx in advance.
Use NSUserDefaults. I don't know how you're app is structured, but that way, you can store some amount of information when the app quits. Next time when you launch, you can check to see if a value exists (NSUserDefaults behaves like NSDictionary), and if it does, start up from there.
Jeff LaMarche has a tutorial on saving the state for tab bar controllers on his blog.
I think you could use a form of persistent storage, like NSUserDefaults, where you could save the application's state, and reload it after each restart. I'm thinking about loaded Nib names and specific controls' properties, depending on your application's logic.

Exchange data between two iPhone child views

Been researching how to send data from one child view to another child view. The application has several views, where one is kind of real-time Settings view. Changes in settings should effect stuff inside other views.
NSUserDefaults seems to be popular, but I don't want persistent data nor automatic saving into database/file. Looks like potential slowdown, which I want to avoid.
Second popular thing is passing a reference to some common top level object into each child view. Just haven't found any tutorial, which would show me in detail how to do this... Most likely so easy, no tutorial is needed - after you figure it out once! Would appreciate, if you can point me to right direction (URL)!
Question: I'm thinking about using one "singleton object" to store "global data", access it from everywhere anytime. What could wrong with this? If I create it at e.g. appDelegate.m it should exist before anyone tries to access it, right?
I'm looking at this sample code.
I would recommend using delegates and/or notifications.
Instead of creating a new singleton in the app delegate, add the necessary data (or, even better, references to the data) in the app delegate and have the views have references to the app delegate.
You can also set up notifications so that your views can keep track of changes to the data that they display.
The beauty of a singleton is that it is automatically created when you first access it via some [singletonClass sharedInstance]. So you don't need to "create" it while launching. If it is global data that needs to be accessed from any view singleton might be the right way of doing this.