Wednesday, February 4, 2009

iPhone Development: Setup Wizard

In this post I am going to access all the preferences from the code. Also I have made a setup wizard which allows you to change the preferences from the application it self.
Following are some of the things covered:
  1. Reading Preferences
  2. Editing Preferences
  3. Custom UITableView
  4. Wizard
The Wizard will finally look like this:
Before we start, lets have a look at NSUserDefaults. This is the class which will be used to access  our preferences. All you need to do is get an instance of this class, after that it is much like a dictionary. For example:
NSUserDefaults *user = [NSUserDefaults standardUserDefault];
[user boolForKey:]
[user stringForKey:]
[user setBool:(BOOL) forKey:

So lets start by adding a new UIViewController subclass in the classes folder. Right click on classes and add new UIViewController subclass, name it as SetupWizard.m.
Before accessing preferences, we need to setup the view for the wizard. So open SetupWizard.h and add the following code:

Here we have created some UI elements which are similar to the ones we have in our application preferences if you remember.
Since we will be using a table view , we have included the tableview delegate and datasource in interface declaration, which also includes UITextFieldDelegate . We will see later why we have used it.
Also we have made 2 cells, here we are diverting from the conventional coding practices, but there is a reason for that which will be clear as we proceed.

For now open SetupWizard.m and add the following code inside loadView method:

This code is simple enough, just a few UI elements being added on the view. If you are not clear what we did in this code then you need to refer my previous posts. 
Important things to note in this code are: we need to have a method named "save" which we have added as a target to the button. 

This is the method where we will be saving the preferences from our application into the Settings so that next time user launches the application, he has the same preferences he had last time. We will understand that in a while.

Before implementing save method, we should not forget we have a tableView added into the view so we have to implement it's protocol methods. Add the following code in SetupWizard.m:

Here we need some description. Why do we need to have 2 cells declared in .h? See the table view in the Wizard image at the beginning of this post. You will notice that this is similar to the one in preferences we made last time. See the image below, it is the multivalue preference we made last time.

If you tried using it then you must have noticed that when you select a cell, it gets checkmarked and only one cell at a time gets checkmarked. To make this happen in our table view, we had to have the access to both the cells all the time. You will understand this after you see what we are going to write in didSelect method of tableViewDelegate. So go on and write the following code:

Did that help? If we went on with the conventional coding style, how do we get access to the cell in didSelectMethod to change the accessory types? You will say that I will make a call to cellForRowAtIndexPath and receive the cell where ever I want. That's correct but you only get the cell corresponding to the indexpath you have, if you want to get other cells by this method, you need to create your own index path. Since we had only 2 cells, we can make our lives simple by avoiding  it.

Now we are going to implement the most awaited "Save" method where we will be accessing preferences. Add the following code in SetupWizard.m

I think the code is self explanatory. If you now build the code and run it, you should be expecting to see what you made just now, right? Wrong! you will see the same hello world screen again and the tableview if you pressed the button. What we are going to do now is push this SetupWizard view from an appropriate place. For now, we will be doing it from MyTableView class we created earlier. So open MyTableView.m and add the following code:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

SetupWizard *wizard = [[SetupWizard alloc]init];

[self.navigationController pushViewController:wizard animated:YES];

Now if you run build and run the project, you can see the wizard by clicking on any row in the table.
You can download the whole code till now from here 

Now, we still have one thing to do. When the user sees the wizard, he should be shown all the previous configurations he chose. For that we will be reading all the preferences and reflecting it in our view. Just add the following code in SetupWizard.m :



NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];

[textField setText: [userDefaults stringForKey:@"url"]];

if([userDefaults integerForKey:@"whichNumber"] == 0)

cell1.accessoryType = UITableViewCellAccessoryCheckmark;


cell2.accessoryType = UITableViewCellAccessoryCheckmark;

[sw setOn:[userDefaults boolForKey:@"switch1"]];

[slider setValue:[userDefaults doubleForKey:@"slider_preference"]];


and call this method from viewDidLoad like this:

- (void)viewDidLoad {

[self loadPreferences];


Now if you build and run the application, every time you will see the previous configurations showing up in the wizard.

Let me know if I have been missing anything.


No comments:

Post a Comment

Leave your suggestions

There was an error in this gadget