Saturday, February 2, 2013

How to use PList files in iPhone Tutorial



wake me up when september ends

here comes the rain again
falling from the stars
drenched in my pain again
becoming who we are.. wake me up when.. 

What's up guys, today we are going to learn one more simple but important concept in iPhone application development.. PLists.

So what is the Plist file?
A property list file is an XML file.The file itself is typically encoded using the Unicode UTF-8 encoding and the contents are structured using XML.Storing data on the iPhone or iPad is fairly simple using plist in Key-Value pairs.



So stay with me, and do it step by step by .. don't forget to drop me a message or comment.

At the end of this Tutorial you can find Complete Source code zip file.

Before starting You may like to know our plist details

  -----------------------------------------------
| Plist file Name : Contacts.plist          |
| Plist Keys Name : Name, Address, PhoneNo  |
  -----------------------------------------------

Note : This Application Developed Using : iOS 6 , Xcode 4.6, and MAC OS X Lion 10.8.1

PHASE - I (Create New Project)

So, Let's Fire Xcode!!

Go to File --> New --> Project

Now we can see a Pop up Window for selecting our application templet 

So make sure you select Application in iOS option on your Left hand side.
then select Single View Application as shown in below picture and Go for Next..



In the Next Window we need to put Our Project Details this way

---------------------------------------------------------------
| Product Name : PListDemo            |
| Organization Name :RDCWorld    |
| Company Identifier : com.rdcworld            |
|                            |
| Class Prefix :  (leave it blank for now)    |
|                            |
| Devices : iPhone                    |
----------------------------------------------------------------

Note : Don't forget to Make Tick mark on "Use Automatic Reference Counting" option.



Go to Next --> Create.

Now you can see Xcode default dashboard with our newly created project .
our project structure is look like 




PHASE - II (Design UI)

We need to add  some UITextFields, UIButtons on our screen to get it work.

So, Just open ViewController.xib file you can see default blank layout

1. TextFields : 
1.1 now drag TextFields for Name ,adjust full width, then go to Attribute Inspector and update Placeholder value as "enter name here" 

1.2 do same for next TextField for Address and change its Placeholder value as "enter address here" 

1.3. drag one more TextField for Phone No and change its Placeholder value as "enter 10 digit phone no" 

2. UIButtons: drag 4 Buttons and double click and give them name as Save in Plist, and  Get Data from Plist respectively .

Now adjust all these items on your Layout as per shown in below screen shot.



PHASE - III (Create IBOutlets and IBAction )

We are going to create IBOutlet for UITextFields and IBAction methods for UIButtons .
So just open ViewController.xib 

Okay, Now select Assistant Editor on Top Right side



You can see our ViewController.xib (Left side) + ViewController.h (Right side) opened together.
1. Create IBOutlets

1.1 Select UITextField (which says - 'enter name here') --> Right Click on it 

1.2 Click on "New Referencing outlet" option and drag cursor to ViewController.h(right side) file, when your cursor is between @interface and @end you can see like this.



1.3 Now you will get Popup Window 

just put Name : "nameTextField" and click on Connect.



you can see below line added in our ViewController's header file

@property (weak, nonatomic) IBOutlet UITextField *nameTextField;

1.4 do the same for next two TextFields and give them name as "addressTextField" and "phoneTextField" respectively 

this time you can see two IBOutlets created in header file


@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet UITextField *phoneTextField;


2. Create IBAction methods
2.1 Select UIButton (which says -'Save in Plist') --> Right Click on it 



2.2 Click on Touchup Inside in  "Sent Events" option and drag cursor just below to new created IBOutlets, and put the method name "saveDataInPlist" in pop window



you can see new method is added in our ViewController's header file

- (IBAction)saveDataInPlist:(id)sender;

2.3 do the same for other Button and give methods name as "getDataFromPlist".

this time you can see one more new IBAction method created in header file

- (IBAction)getDataFromPlist:(id)sender;

Done!! now back to Standard Editor

Screen 10


PHASE - iV (Writing Code)

~ ~ ~ ~ ~ ~ ~ ~ ~              Controller Class (ViewController)          ~ ~ ~ ~ ~ ~ ~ ~ ~  


We have added some IBOutlets and IBActions into our header file

So Finally our ViewController.h file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.h
//  PListDemo
//
//  Created by RDC on 9/2/12.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UITextField *nameTextField;
@property (weak, nonatomic) IBOutlet UITextField *addressTextField;
@property (weak, nonatomic) IBOutlet UITextField *phoneTextField;


- (IBAction)saveDataInPlist:(id)sender;
- (IBAction)getDataFromPlist:(id)sender;

@end
-----------------------------------------------------------------------------------------------------------------------------------------

Now come to ViewController.m file , open it

1. add synthesize (for all declared variable in header file with @property) just below to @implementation

@synthesize nameTextField;
@synthesize addressTextField;
@synthesize phoneTextField;

2. update the body of saveDataInPlist method

- (IBAction)saveDataInPlist:(id)sender {
    
    //get the plist document path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];    
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSMutableDictionary *data = [[NSMutableDictionary alloc]init];
    NSMutableArray *contentArray= [[NSMutableArray alloc]init];
    
    if (![fileManager fileExistsAtPath: plistFilePath])
    {
        NSLog(@"File does not exist");
        
        // If the file doesn’t exist, create an empty plist file        
        plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
        //NSLog(@"path is %@",plistFilePath);
        
    }
    else{
        NSLog(@"File exists, Get data if anything stored");
        
        contentArray = [[NSMutableArray alloc] initWithContentsOfFile:plistFilePath];       
    }       
    
    
    NSString *name = nameTextField.text;
    NSString *address = addressTextField.text;
    NSString *phone = phoneTextField.text;
    
    //check all the textfields have values
    if (([name length] >1) && ([address length] >1 )&& ([phone length] >1)) {
        
        //add values to dictionary
        [data setValue:name forKey:@"Name"];
        [data setValue:address forKey:@"Address"];
        [data setValue:phone forKey:@"PhoneNo"];
        
        //add dictionary to array
        [contentArray addObject:data];
        
        //write array to plist file
        if([contentArray writeToFile:plistFilePath atomically:YES]){
            
            NSLog(@"saved");
            
            nameTextField.text = @"";
            addressTextField.text =@"";
            phoneTextField.text =@"";
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Saved in plist" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];          
            
        }
        else {
            NSLog(@"Couldn't saved");
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Couldn't Saved in plist" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];
        }
    }
    else{
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Please! enter values" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert show];                
    }   
}

Let me explain what we doing in this method.

2.1 First of all we get the Document folder path of our application.

For my case I can see this plist file at below path

/Users/RDCMac/Library/Application Support/iPhone Simulator/6.1/Applications/37234831-EE6A-41FB-9DDE-FE9BDAE6E53C/Documents/Contacts.plist

Note : you need to enable hidden files on your MAC system to see this file

2.2 then we checked file is exited or not at this path

2.3 if file is already there,read the data into content array if any, else create new empty plist file.

2.4 we read the text from TextFiles and added to Dictionary using Keys

2.5 and added result dictionary to content array 

2.6 finally we are writing content array to the plist file.

3. now update the body of getDataFromPlist method

- (IBAction)getDataFromPlist:(id)sender {
    
    //get the plist document path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSMutableDictionary *data = [[NSMutableDictionary alloc]init];
    NSMutableArray *contentArray= [[NSMutableArray alloc]init];
    
    if (![fileManager fileExistsAtPath: plistFilePath])
    {
        NSLog(@"file does not exist");
        
        // If the file doesn’t exist, create an empty plist file
        plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
        
    }
    else{
        
        NSLog(@"File exists, Get data if anything stored");
        contentArray = [[NSMutableArray alloc] initWithContentsOfFile:plistFilePath];
        NSLog(@"contant array is %@",contentArray);
        
    }   
    
    //print the plist result data on console
    for (int i= 0; i<[contentArray count]; i++) {
        
        data= [contentArray objectAtIndex:i];
        NSString *name = [data objectForKey:@"Name"];
        NSString *address = [data objectForKey:@"Address"];
        NSString *phone = [data objectForKey:@"PhoneNo"];
        
        NSLog(@"Data From Plist: Name = %@, Address=%@, Phone=%@",name,address,phone);
    }
}

So Finally our ViewController.m file look like

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  ViewController.m
//  PListDemo
//
//  Created by RDC on 9/2/12.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
@end

@implementation ViewController

@synthesize nameTextField;
@synthesize addressTextField;
@synthesize phoneTextField;


#pragma mark - ViewController's life cycle methods

- (void)viewDidLoad
{
    [super viewDidLoad];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];    
}

#pragma mark - Create Plist and store data method

- (IBAction)saveDataInPlist:(id)sender {
    
    //get the plist document path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];    
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSMutableDictionary *data = [[NSMutableDictionary alloc]init];
    NSMutableArray *contentArray= [[NSMutableArray alloc]init];
    
    if (![fileManager fileExistsAtPath: plistFilePath])
    {
        NSLog(@"File does not exist");
        
        // If the file doesn’t exist, create an empty plist file        
        plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
        //NSLog(@"path is %@",plistFilePath);
        
    }
    else{
        NSLog(@"File exists, Get data if anything stored");
        
        contentArray = [[NSMutableArray alloc] initWithContentsOfFile:plistFilePath];       
    }       
    
    
    NSString *name = nameTextField.text;
    NSString *address = addressTextField.text;
    NSString *phone = phoneTextField.text;
    
    //check all the textfields have values
    if (([name length] >1) && ([address length] >1 )&& ([phone length] >1)) {
        
        //add values to dictionary
        [data setValue:name forKey:@"Name"];
        [data setValue:address forKey:@"Address"];
        [data setValue:phone forKey:@"PhoneNo"];
        
        //add dictionary to array
        [contentArray addObject:data];
        
        //write array to plist file
        if([contentArray writeToFile:plistFilePath atomically:YES]){
            
            NSLog(@"saved");
            
            nameTextField.text = @"";
            addressTextField.text =@"";
            phoneTextField.text =@"";
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Saved in plist" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];          
            
        }
        else {
            NSLog(@"Couldn't saved");
            
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Couldn't Saved in plist" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
            [alert show];
        }
    }
    else{
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Please! enter values" delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil, nil];
        [alert show];                
    }   
}


#pragma mark - get data from plist method

- (IBAction)getDataFromPlist:(id)sender {
    
    //get the plist document path
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    NSMutableDictionary *data = [[NSMutableDictionary alloc]init];
    NSMutableArray *contentArray= [[NSMutableArray alloc]init];
    
    if (![fileManager fileExistsAtPath: plistFilePath])
    {
        NSLog(@"file does not exist");
        
        // If the file doesn’t exist, create an empty plist file
        plistFilePath = [documentsDirectory stringByAppendingPathComponent:@"Contacts.plist"];
        
    }
    else{
        
        NSLog(@"File exists, Get data if anything stored");
        contentArray = [[NSMutableArray alloc] initWithContentsOfFile:plistFilePath];
        NSLog(@"contant array is %@",contentArray);
        
    }   
    
    //print the plist result data on console
    for (int i= 0; i<[contentArray count]; i++) {
        
        data= [contentArray objectAtIndex:i];
        NSString *name = [data objectForKey:@"Name"];
        NSString *address = [data objectForKey:@"Address"];
        NSString *phone = [data objectForKey:@"PhoneNo"];
        
        NSLog(@"Data From Plist: Name = %@, Address=%@, Phone=%@",name,address,phone);
    }
}

@end
-----------------------------------------------------------------------------------------------------------------------------------------

~ ~ ~ ~ ~ ~ ~ ~ ~              Application Delegate Class (AppDelegate)          ~ ~ ~ ~ ~ ~ ~ ~ ~  


Make sure your AppDelegate file code should be default 

Finally our AppDelegate.h file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.h
//  PListDemo
//
//  Created by RDC on 9/2/12.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import <UIKit/UIKit.h>

@class ViewController;

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@property (strong, nonatomic) ViewController *viewController;

@end-----------------------------------------------------------------------------------------------------------------------------------------


Finally our AppDelegate.m file look like 

-----------------------------------------------------------------------------------------------------------------------------------------
//
//  AppDelegate.m
//  PListDemo
//
//  Created by RDC on 9/2/12.
//  Copyright (c) 2013 RDCWorld. All rights reserved.
//

#import "AppDelegate.h"

#import "ViewController.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];
    return YES;
}

//for now leave rest all empty methods..

@end
-----------------------------------------------------------------------------------------------------------------------------------------


Okay wrap it up this application. let's Run it.

Here is the output I entered contact details and saved into plist file.




Cheers!! we did it. 


You can find complete project source code zip file here : PListDemo.zip (75.81 KB)


I Would love to here your thoughts !! 

No comments:

Post a Comment