Wednesday, April 21, 2010

IPhone Programming Tutorial - XML Login Screen

IPhone Programming Tutorial - UserName and Password Login screen



Lesson Description:
in this lesson we will create a basic unencrypted login and password screen.
we will learn about:
            *UITextField
            * UIButton
            * Adding events to controls
            * parsing XML file and comparing it's content

Tutorial:
1. launch XCode .
2. click: File->New Project…
and choose: View-based Application
name the project: 'XMLLogin'
when you choose view-based application XCode creates for you the following additional files:
Classes\XMLLoginViewControl.h
Classes\XMLLoginViewControl.m
Resources\XMLLoginViewControl.xib
the XMLLoginViewControl.xib is the design of the view
the other files are used for the class files for the view
and also XCode creates the view and puts it as the main screen when the program launches.
3. double click Resources\XMLLoginViewControl.xib
the Interface Builder should launch
4. from the library put the controls needed:
            * drag  UILabel to the left top corner of the screen double click and change           the text to: 'Username:'
            * drag  UILabel and put it under the previous label double click and change          the text to: 'Password:'
            * drag  UILabel and put it under the previous label double click and change          the text to: 'Login Status'
            * drag UITextField and put it next to the Username label
            * drag UITextField and put it next to the Password label
            * drag UIButton and put it in the middle of the screen bellow all the label and       textFields . double click and change the name to Login
5. save interface Builder and build and run your program
you will notice that the view that you edit in interface builder launches and the screen that you designed pops up. try and play a little with the button and text fields.
notice anything strange?
try and click the UITextField you will notice that the keyboard pops up but unfortunately the keyboard does't disappear when you click the return key or tap on the background.
so let's make the keyboard disappear when you click enter .



6. open XMLLoginViewController.h and add this code
#import
@interface XMLLoginViewController : UIViewController {
         UITextField *txtUsername, *txtPassword;
}
@property (nonatomic,retain) IBOutlet UITextField *txtUsername;
@property (nonatomic,retain) IBOutlet UITextField *txtPassword;
- (IBAction)returnClicked:(UITextField *)sender;
- (IBAction)clickBackground:(id)sender;
@end

we declare here two variables of type UITextField that will be connected with the two textFields we have on our view, and we add property to the variables so that the interface builder can get and set their properties.
We also added here two methods:
the first one is used to capture the event of return clicked in the UITextField's
the second one is to capture the event of user clicking the background .

7. open XMLLoginViewController.h and it this code between @implementation @end:

- (IBAction)returnClicked:(UITextField *)sender{
         [sender resignFirstResponder];
}

- (IBAction)clickBackground:(id)sender{
         [txtPassword resignFirstResponder];
         [txtUsername resignFirstResponder];
}

we add code for the two methods we declared in the header.
the code makes the keyboard disappear when return or background is clicked.

8. we will have to connect our controls to our vars and methods
so open up interface builder press control and drag from our file manager to the username text box and choose txtUsername.
for the password do the same and choose txtPassword.
choose the username textField and from the tools menu choose connection inspector drag from the did end on exit event to the file manager and choose returnClicked:
do the same with the other textField .
for the view we will want to add a click event to capture the clicking on the background. unfortunately we cant see a touch up inside event for the view. so click on the view and click tools identity inspector and change the class to UIControl.
now you can find in the connection inspector the touch up inside event so connect it to the file manager and choose clickBackground: .
9. if you build and go you will see the keyboard disappears whenever we click the return or background .





lets add the main functionality of this program the Login Successfully or Login Failed.
for this part you will need an xml file with the structure like the one in this URL: http://ywarezk.webs.com/password.xml
10. change the code in XMLLoginViewController.h to look like this:
#import

@interface XMLLoginViewController : UIViewController {
         UITextField *txtUsername, *txtPassword;
         NSXMLParser * xmlParser;
         NSMutableArray * users;  
         NSMutableDictionary * item;
         NSString * currentElement;
         NSMutableString * currentUser, * currentPassword;
         UILabel *lblLoginStatus;
}

@property (nonatomic,retain) IBOutlet UITextField *txtUsername;
@property (nonatomic,retain) IBOutlet UITextField *txtPassword;
@property (nonatomic,retain) IBOutlet UILabel *lblLoginStatus;

- (IBAction)returnClicked:(UITextField *)sender;
- (IBAction)clickBackground:(id)sender;
-(IBAction)loginPressed:(id)sender;

@end

as you can see we added NSXMLParser object - this is the objects that are used to manipulate xml in iphone.
we also added NSMutableArray we called users this will contain array of objects that each object contain username and password.
we declared an NSMutableDictionary called item - this will contain the object that will contain the username and password of the item from the xml that we are currently reading.
currentElement - is the string that contains the xml element that we are currently processing.
currentuser and currentpassword will be the string with the username and password of the current xml element that is being processed.
lblLoginStatus - is a label that we reference from the login status label we added in interface builder.
we also added an action for the login button pressed.

11. go to XMLLoginViewController.m and add this code that will initialize the xml parser and set the delegate - we add this code in the viewDidLoad method so you will need to uncomment the function.
- (void)viewDidLoad {
    [super viewDidLoad];
         users = [[NSMutableArray alloc] init];
         NSURL *xmlURL = [NSURL URLWithString:@"http://ywarezk.angelfire.com/user.xml"];
         xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
         [xmlParser setDelegate:self];
         [xmlParser parse];
}

the [super viewDidLoad] command activates the viewDidLoad method of the super (class we inherit from)
we initiate the array that will contain the users data
the NSXmlParser library works with NSURL type so we must initiate this type with the url of the xml we want to read
we allocate our NSXMLParser var with the url
we set the delegate of our var to self this means that the object will activate its method from functions from this class
we use the parse command to start the parsing .






12. after we set our xml object we need to  override the methods of the NSXMLParser so add these methods to XMLLoginViewController.m:
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
         currentElement = [elementName copy];
         if ([elementName isEqualToString:@"User"]) {
            item = [[NSMutableDictionary alloc] init];
            currentUser =[[NSMutableString alloc] init];
            currentPassword =[[NSMutableString alloc] init];
         }
}

this method is called when the parser encounters the start of an element
if the element is equal to User we allocate item username and password for the element






13. lets overide the method for the end of every element. add this function to XMLLoginViewController.m:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
         if ([elementName isEqualToString:@"User"]) {
            [item setObject:currentUser forKey:@"Username"];
            [item setObject:currentPassword forKey:@"Password"];
            [users addObject:[item copy]];
         }
}
in this function we check if the element that just ended is a User element and if it is he puts all the data (username , password) to our item and puts the item in out users array .
notice the forkey we use because it will later be importuned when we try to pull the data out of the item.

14.  we have to make sure that the data of the username and password will get to their appropriate variables so we add override for the fundcharacters method that is launched when every character in the document is detected
add this method to XMLLoginViewController.m:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
         if ([currentElement isEqualToString:@"Username"]) {
            [currentUser appendString:string];
         }
         if ([currentElement isEqualToString:@"Password"]) {
            [currentPassword appendString:string];
         }
}

if our element is username or password we keep our appropriate vars updated in this function





ok now we are almost done. we added the necessary xml functionality and we now have the users array that contain all the users that are allowed to login . now lets add the login button click functionality . this function will compare the login and password that is entered to our users array .
add this code to XMLLoginViewController.m:

-(IBAction)loginPressed:(id)sender{
         for (NSMutableDictionary *val in users) {                    
            NSMutableString *usrname = [val objectForKey:@"Username"];
            NSMutableString *psswrd = [val objectForKey:@"Password"];
            usrname=[usrname stringByReplacingOccurrencesOfString:@"\n" withString:@""];
            usrname=[usrname stringByReplacingOccurrencesOfString:@"\t" withString:@""];
            psswrd=[psswrd stringByReplacingOccurrencesOfString:@"\n" withString:@""];
            psswrd=[psswrd stringByReplacingOccurrencesOfString:@"\t" withString:@""];
            if([usrname isEqualToString:[txtUsername text]]&&[psswrd isEqualToString:[txtPassword text]]){
                        [lblLoginStatus setText:@"Login Successful!!"];
                        return;
            }
         }
         [lblLoginStatus setText:@"login failed"];
         return;
}

in this function we loop on the users array and extract the data from each item with the objectForKey that uses the forKey we specified earlier after that we compare each value with the text from our textfields and if we have a mach we change the text in the login status label.

15. lets connect everything that is needed from the interface builder so double click XMLLoginViewControl.xib to launch interface builder.
press control and drag from file manager to our login status label and choose lblLoginStatus . now click the button and in the connection inspector drag from touch up inside to file manager and choose loginPressed:






16. for finish lets free all the allocated memory add this to the dealloc method in XMLLoginViewController.m:
- (void)dealloc {
         [txtPassword release];
         [txtUsername release];
         [lblLoginStatus release];
         [currentPassword release];
         [currentUser release];
         [currentElement release];
         [users release];
         [item release];
    [super dealloc];       
}

all done try and launch the program and play a little with the results.
you have the full source files for download bellow .
for any questions you have feel free to ask in the blog.
thank you for reading






14 comments:

  1. hi can u post the project files for the login page project ?
    i m having some problems with ur source codes

    ReplyDelete
  2. opps it seems i solve the error myself=D btw thx for the great guide.
    I m new to iphone sdk programming, i m wondering if it possible to login to sql instead of xml with your above tuts ?

    ReplyDelete
  3. it is possible to create an sqllite database to your app containing usernames and pasword and do the same thing i did in this tutorial with the databse.
    there is a nice guide for sqllite in iphone in this link
    http://icodeblog.com/2008/08/19/iphone-programming-tutorial-creating-a-todo-list-using-sqlite-part-1/

    hope it helps

    ReplyDelete
  4. Thank you for your reply ywarezk!! =D
    Your help is greatly appreciated and thank you for the link on sql =D

    Cheers man !! you have been a great help =)

    ReplyDelete
  5. wow.. this was a great tutorial.. thank you very much.

    could u please tell me where the source files are located on the page?

    ReplyDelete
  6. the info shown here on the screen is not the same as the code you use on the videos.....what's up with that? A source file would clarify a lot of confusion at this point. I entered the code as you entered in the videos, and it will not confirm the password was entered correctly. Not to mention the LEAKS that occur. Can you help us with this?

    ReplyDelete
  7. Your tutorial helps me alot..thanks.!!but i am stucking with warning [xmlParser setDelegate:self]; //incompatiable to load XMLLoginViewController to NSXMLParser..
    i am alwas leads to login failed case..because of this..i got this is only error..nothing else.

    ReplyDelete
  8. the tutorial was a blast.. thank u very much ywarezk for the tutorial. Can you please tell us where the source file download link is located :)

    ReplyDelete
  9. Hi,
    Your tutorial Is the startinh page of my project.
    Thanks a lot.
    Can y send me the app.And have to know the passwora and username. mohammedrafiq82@gmail.com
    Thank u

    ReplyDelete
  10. Hey everyone i need a bit help!

    I done everything correct and when i tested the app worked fine but when i change the link of the XML file to my localhost or my domain it doesn't worked.

    Someone can show me the script of xml file

    ReplyDelete
  11. Hello ywarezk. I need alot of help with making an app that uses data from xml. I was wondering if you could help me... If you can, please send me an email at elias.baez@me.com... I would really appreciate the help :)

    ReplyDelete
  12. How do you make more than one password and username? I can't do that. please help

    ReplyDelete
  13. This comment has been removed by the author.

    ReplyDelete