Phonebook

Phonebook application tutorial

1.Creating the project

In this project we will create a Simple phonebook. Given a list of people from an xml file that we create the application presents it to the user using a UITableView. We will also implement “add” and “delete” contact actions, but since writing to a file would be beyond the scope of this tutorial, the changes will not be saved.

First we need to add the phonebook.xml to the project’s recourses folder (which is src/main/artwork).

(Download phonebook.xml )

The next step is to change the Emulated environment theme to “Bright theme” (Plugins→ Set Theme). This changes the look and feel on the Android and Desktop Versions to iOS 5 equivalent.

2.Starting to Code

Below is all the procedure you follow in order to construct your the phonebook project step by step. We are going to use NetBeans IDE as we did previously.

First of all you need to add a new class and name it Person. Person will be the class that will hold the information of each contact. Class person has three properties (name, surname, phone) and also the getters/setters for each property.

Feel free to add more properties for each person if you want but be sure that you implement their equivalent methods in the other classes. Person’s code is the following:

public class Person { 

    private String name; 
    private String surname; 
    private String phone; 

    public Person() { 
    } 

    public Person(String name, String surname, String phone) { 
        this.name = name; 
        this.surname = surname; 
        this.phone = phone; 
    } 

    public String getName() { 
        return name; 
    } 

    public void setName(String name) { 
        this.name = name; 
    } 

    public String getSurname() { 
        return surname; 
    } 

    public void setSurname(String surname) { 
        this.surname = surname; 
    } 

    public String getPhone() { 
        return phone; 
    } 

    public void setPhone(String phone) { 
        this.phone = phone; 
    } 

}

Next we are going to create a class to handle xml parsing. This class uses the xml file with the contacts and matches them to List Person.

First of all we need to get the path of our xml. To do so we declare NSBundle.mainBundle().pathForResource(“phonebook”, “xml”) in the constructor. This method points to the file in the recourses. (Note that the NSBundle resources are read-only). The code you are going to create is the following:

public class XMLHandler {

    private final NSXMLParser xmlparser;
    private final ParserDelegate deleg;
    private final String path;
    private List<Person> phonebook;

    public XMLHandler() {
        path = NSBundle.mainBundle().pathForResource("phonebook", "xml");
        System.out.println(path==null?"null":path);
        NSData xmldata = NSData.dataWithContentsOfFile(path);
        xmlparser = new NSXMLParser(xmldata);
        deleg = new ParserDelegate();
        xmlparser.setDelegate((NSXMLParserDelegate) deleg);
    }

    public List<Person> parceXML() {
        xmlparser.parse();
        phonebook = deleg.getPhoneBook();
        return phonebook;
    }

    public List<Person> addContact(Person person) {
        phonebook.add(person);
        return phonebook;
    }

    public List<Person> removeContact(Person person) {
        phonebook.remove(person);

        return phonebook;
    }

}

As you can see we create an NSData Object and pass the contents of file and we initialize an NSXMLParser Object with that data.

Create a ParserDelegate class that will implement the delegate that will handle the parsing and set it as the NSXMLParser’s Object delegate.

After that, we create three methods:

  • parceXML() method calls the parser and takes the phonebook from the delegate and returns it.
  • addContact() that adds a person to the phonebook
  • removeContact that removes a contact from our list.

Next we create the ParserDelegate class that extends NSXMLParserDelegate and implements didStartElenent() method. This method is called when the parser finds the start-tag of an element, since we use empty-element tags with attributes, that is the only method we need.

We check if the element’s tag is “person”, we create a new Person with the element’s attributes.

Finally, we add that person to the phonebook List. We also add a method to the delegate that returns the phonebook. Below is our ParserDelegate class code:

public class ParserDelegate implements NSXMLParserDelegate {

    private final List<Person> phonebook = new ArrayList<>();

    @Override
    public void didStartElement(NSXMLParser parser, String elementName, String namespaceURI, String qualifiedName, Map<String, String> attributes) {
        if (elementName.equals("person")) {
            Person person = null;

            try {
                person = new Person(attributes.get("name"), attributes.get("surname"), attributes.get("phone"));
            } catch (Exception ex) {
            }
            phonebook.add(person);
        }
    }

    public List<Person> getPhoneBook() {
        return phonebook;
    }
}

3.Creating the UITableViewCell

First we are going to create a class Cell that extends UITableViewCell and will implement the contents of each cell.

We add a constructor that takes a phonebook as parameter, initializes the cell to the Default Style and passes the phonebook to a field. Next we add an update() method that takes the cell’s index as parameter and fills the cell with its contents.

The second parameter of the super Constructor sets “Cell” as the Cell’s unique identifier.

For the needs of this example we set the cell’s textLabel with the name and surname of each contact and an invisible button that pushes a ViewControler containing the contact’s info (we’ll get to that later). In order to access the navigation Controller from within the cell, which is not on the UINavigationController’s stack of views, we take it from

UIApplication.sharedApplication().keyWindow().rootViewController() , which we cast to UINavigationController.

So the code of our Cell class is the following:

public class Cell extends UITableViewCell {

    private final List<Person> phonebook;

    public Cell(List<Person> phonebook) {
        super(UITableViewCellStyle.Default, "Cell");
        this.phonebook = phonebook;
    }

    public void update(final int index) {
        textLabel().setText(phonebook.get(index).getName() + " " + phonebook.get(index).getSurname());
        UIButton cellButton = UIButton.buttonWithType(UIButtonType.Custom);
        cellButton.setFrame(new CGRect(0, 0, 320, 35));
        cellButton.setBackgroundColor(UIColor.clearColor());

        cellButton.addTarget(new UIControlDelegate() {

            @Override
            public void exec(UIControl arg0, UIEvent arg1) {
                ((UINavigationController) UIApplication.sharedApplication()
                        .keyWindow().rootViewController())
                                .pushViewController(new PersonController(phonebook.get(index)), true);
            }

        }, UIControlEvents.TouchUpInside);
        contentView().addSubview(cellButton);
    }

}

After that we go to the ViewController class and we add our width and height fields, initialize the phonebook, declare the XMLHandler and initialize the table with the following declaration:

private final UITableView table = new UITableView(new CGRect(0, 0, dWidth, dHeight), UITableViewStyle.Plain);

That adds a full screen table view.

In the loadView method we first take the phonebook from the xml and then we set the table’s data source by implementing the anonymous class UITableViewDataSource. We implement two methods, the

numberOfRowsInSection(UITableView table, int section) method that returns the number of rows the table will have (in this case the phonebook’s size) and the UITableViewCell cellForRowAtIndexPath(final UITableView table, final NSIndexPath idx) method that adds a cell in each row.

To do that we first check if there is a cell insance that can be recycled with the “Cell” unique identifier by calling

Cell cell = (Cell) table.dequeueReusableCellWithIdentifier("Cell");
If there aren’t any (dequeueReusableCellWithIdentifier() return null) we create a cell.

Finaly we call update with the cells index as parameter to fill its contents and we return that cell.

public class ViewController extends UIViewController {
    float dHeight = UIScreen.mainScreen().bounds().size.height;
    float dWidth = UIScreen.mainScreen().bounds().size.width;
    private final UITableView table = new UITableView(new CGRect(0, 0, dWidth, dHeight), UITableViewStyle.Plain);
    List<Person> phonebook = new ArrayList<>();
    XMLHandler xml;

    @Override
    public void loadView() {
        UIView mainView = new UIView();
        mainView.setBackgroundColor(UIColor.whiteColor());

        xml = new XMLHandler();
        phonebook = xml.parceXML();

        table.setDataSource(new UITableViewDataSource() {

            @Override
            public UITableViewCell cellForRowAtIndexPath(final UITableView table, final NSIndexPath idx) {
                Cell cell = (Cell) table.dequeueReusableCellWithIdentifier("Cell");
                if (cell == null)
                    cell = new Cell(phonebook);
                cell.update(idx.row());
                return cell;
            }

            @Override
            public int numberOfRowsInSection(UITableView table, int section) {
                return phonebook.size();
            }
        });

        mainView.addSubview(table);
        setView(mainView);
    }
}

4.Adding two more ViewControllers

Now we can create the view controller that will show the contact info when we press a cell.

This class puts six labels on its View, three descriptive (“name”, “surname”, “phone”) and three dynamic that contain the contents of the Person passed at the constructor.

public class PersonController extends UIViewController { 

    private final Person person; 
    float dHeight = UIScreen.mainScreen().bounds().size.height; 
    float dWidth = UIScreen.mainScreen().bounds().size.width; 

    public PersonController(Person person) { 
        this.person = person; 
    } 

    @Override 
    public void loadView() { 
        UIView view = new UIView(); 
        view.setBackgroundColor(UIColor.whiteColor()); 

        UILabel name_label = new UILabel(new CGRect(50, 100, 100, 50)); 
        name_label.setText("Name :"); 
        UILabel surname_label = new UILabel(new CGRect(50, 150, 100, 50)); 
        surname_label.setText("Surname :"); 
        UILabel phone_label = new UILabel(new CGRect(50, 200, 100, 50)); 
        phone_label.setText("Phone :"); 
        UILabel name_text = new UILabel(new CGRect(150, 100, 100, 50)); 
        name_text.setText(person.getName()); 
        UILabel surname_text = new UILabel(new CGRect(150, 150, 100, 50)); 
        surname_text.setText(person.getSurname()); 
        UILabel phone_text = new UILabel(new CGRect(150, 200, 100, 50)); 
        phone_text.setText(person.getPhone()); 

        view.addSubview(name_label); 
        view.addSubview(surname_label); 
        view.addSubview(phone_label); 
        view.addSubview(name_text); 
        view.addSubview(surname_text); 
        view.addSubview(phone_text); 

        setView(view); 
    }

The last View Controller is the AddPersonController. This controller is very similar to the previous one, the only difference is that we replace the dynamic labels with textfields. Two with return key types next and one with done. To make the next and done keys work we add delegates to each textfield and we implement the textFieldShouldReturn(UITextField textField) method in each delegate. This method is called when the return key is pressed. The first responder is the textfield that has the keyboards attention, so for the first two textfields we resign them as first responder when the return key is pressed (it will appear as next key on the keyboard) and we assign the next textfield as first responder, while at the last textfield we just resign it from first responder to make the keyboard disappear. Notice that you are allways able to change textfields by selecting them on the screen. And below is the code of our class:

public class AddPersonController extends UIViewController { 

    float dHeight = UIScreen.mainScreen().bounds().size.height; 
    float dWidth = UIScreen.mainScreen().bounds().size.width; 
    final UITextField name_text = new UITextField(new CGRect(150, 100, 100, 50)); 
    final UITextField surname_text = new UITextField(new CGRect(150, 150, 100, 50)); 
    final UITextField phone_text = new UITextField(new CGRect(150, 200, 140, 50)); 

    @Override 
    public void loadView() { 
        UIView view = new UIView(); 
        view.setBackgroundColor(UIColor.whiteColor()); 

        UILabel name_label = new UILabel(new CGRect(50, 100, 100, 50)); 
        name_label.setText("Name :"); 
        UILabel surname_label = new UILabel(new CGRect(50, 150, 100, 50)); 
        surname_label.setText("Surname :"); 
        UILabel phone_label = new UILabel(new CGRect(50, 200, 100, 50)); 
        phone_label.setText("Phone :"); 

        name_text.setPlaceholder("name"); 
        name_text.setReturnKeyType(UIReturnKeyType.Next); 

        surname_text.setPlaceholder("surname"); 
        surname_text.setReturnKeyType(UIReturnKeyType.Next); 

        phone_text.setPlaceholder("phone"); 
        phone_text.setKeyboardType(UIKeyboardType.Default); 
        phone_text.setReturnKeyType(UIReturnKeyType.Done); 

        name_text.setDelegate(new UITextFieldDelegate() { 

            @Override 
            public boolean textFieldShouldReturn(UITextField textField) { 
                name_text.resignFirstResponder(); 
                surname_text.becomeFirstResponder(); 
                return false; 
            } 
        }); 

        surname_text.setDelegate(new UITextFieldDelegate() { 

            @Override 
            public boolean textFieldShouldReturn(UITextField textField) { 
                surname_text.resignFirstResponder(); 
                phone_text.becomeFirstResponder(); 
                return false; 
            } 
        }); 

        phone_text.setDelegate(new UITextFieldDelegate() { 

            @Override 
            public boolean textFieldShouldReturn(UITextField textField) { 
                phone_text.resignFirstResponder(); 
                return true; 
            } 
        }); 

        view.addSubview(name_label); 
        view.addSubview(surname_label); 
        view.addSubview(phone_label); 
        view.addSubview(name_text); 
        view.addSubview(surname_text); 
        view.addSubview(phone_text); 

        setView(view); 
    }

5.Handling the navigation bar

At this point we need to add a UINavigationManager to the ApplicationDelegate class

public class ApplicationDelegate implements UIApplicationDelegate {

    private UIWindow window;

    @Override
    public boolean didFinishLaunchingWithOptions(UIApplication app, Map<String, Object> launchOptions) {
        window = new UIWindow(UIScreen.mainScreen().bounds());
        UINavigationController nav = new UINavigationController(new ViewController());
        window.setRootViewController(nav);
        window.makeKeyAndVisible();
        return true;
    }
}

Next we are going to add to each class a button and also a title on the navigation bar.

Go to the ViewController and implement the viewDidAppear method that calls reloadData() for the table to make sure that every time the app returns from another view the table will reload the changes.

Also implement the viewDidLoad() method. In the viewDidLoad method we access the UIControllView’s navigationItem property to set the views title to “Phonebook” and add a button, initialized as the system item add (which is the plus sign “+”), that will push a new AddPersonController.

    @Override
    public void viewDidAppear(boolean animated) {
        table.reloadData();

    }

    @Override
    public void viewDidLoad() {
        navigationItem().setTitle("PhoneBook");
        UIBarButtonItem add = new UIBarButtonItem(UIBarButtonSystemItem.Add, () -> {
            navigationController().pushViewController(new AddPersonController(), true);
            table.reloadData();
        });
        navigationItem().setRightBarButtonItem(add);
    }

Go to The AddPersonController class and implement the viewDidLoad method to make the name textfield the first responder so the keyboard appears when the view loads, set the view’s title to Add Contact and add a button “Add”.

When clicked we need to call XMLParser class’s method addContact(), to do that we take the ViewController’s intstace from the stack with ((ViewController) navigationController().viewControllers().get(0) (since the ViewController is the first added on the stack, it is at index 0 on the list) and we call the addContact() method with the xml object with a new person as parameter.

Finally, we pop the view controller to go to the main view.

    @Override 
    public void viewDidLoad() { 
        name_text.becomeFirstResponder();
        navigationItem().setTitle("Add Contact");
        UIBarButtonItem add = new UIBarButtonItem("Add", UIBarButtonItemStyle.Plain, () -> {
            ((ViewController) navigationController().viewControllers().get(0)).xml.addContact(new Person(name_text.text(), surname_text.text(), phone_text.text()));
            navigationController().popViewControllerAnimated(true);

        });

        navigationItem().setRightBarButtonItem(add, true);
    }

Go to the PersonController class and create the viewDidLoad method. Set the title to the persons name and add a delete button to the navigation bar.

In UIBarButtoItem’s action lamda create a UIAllertController with the title “warning”, the message “Are u sure?” and Alert style, so that when the user presses delete a confirmation message will appear.

We want our alert to have two actions, one that confirms the contacts deletion and one that prevents it. We add the first action to the alert with title “delete”, style destructive, and a

new BlockInput() to implement what the action does. There we call remove contact from ViewController and we pop the ViewController.

The second button is the back button which is initialized with title “Back”, style Cancel and null as action so that the alert will disappear and go back to the PersonController.

To make the alert appear call presentModalViewController(alert, true); in the clicked method.

    @Override
    public void viewDidLoad() {
        navigationItem().setTitle(person.getName());
        UIBarButtonItem add = new UIBarButtonItem("Delete", UIBarButtonItemStyle.Plain, () -> {

                UIAlertController alert = UIAlertController.alertControllerWithTitle("Warning", "Are u sure?", UIAlertControllerStyle.Alert);
                alert.setMessage("Are u sure?");

                alert.addAction(UIAlertAction.actionWithTitle("Delete", UIAlertActionStyle.Destructive, new BlockInput<UIAlertAction>() {

                    @Override
                    public void exec(UIAlertAction arg0) {
                        ((ViewController) navigationController().viewControllers().get(0)).xml.removeContact(person);
                        navigationController().popViewControllerAnimated(true);
                    }
                }));

                alert.addAction(UIAlertAction.actionWithTitle("Back", UIAlertActionStyle.Cancel, null));
                presentModalViewController(alert, true);

        });

        navigationItem().setRightBarButtonItem(add);
    }

6.The final result

7.The whole Code

Main.java

/*
 * This project was created with CrossMobile library.
 * More info at https://crossmobile.org
 */

package crossmobile.projects.phonebook;

import crossmobile.ios.uikit.UIApplication;

public class Main {

    public static void main(String[] args) {
        UIApplication.main(args, null, ApplicationDelegate.class);
    }
}

ApplicationDelegate.java

/*
 * This project was created with CrossMobile library.
 * More info at https://crossmobile.org
 */

package crossmobile.projects.phonebook;

import crossmobile.ios.uikit.UIApplication;
import crossmobile.ios.uikit.UIApplicationDelegate;
import crossmobile.ios.uikit.UINavigationController;
import crossmobile.ios.uikit.UIScreen;
import crossmobile.ios.uikit.UIWindow;
import java.util.Map;

public class ApplicationDelegate implements UIApplicationDelegate {

    private UIWindow window;

    @Override
    public boolean didFinishLaunchingWithOptions(UIApplication app, Map<String, Object> launchOptions) {
        window = new UIWindow(UIScreen.mainScreen().bounds());
        UINavigationController nav = new UINavigationController(new ViewController());
        window.setRootViewController(nav);
        window.makeKeyAndVisible();
        return true;
    }
}

ViewController.java

/*
 * This project was created with CrossMobile library.
 * More info at https://crossmobile.org
 */

package crossmobile.projects.phonebook;

import crossmobile.ios.coregraphics.CGRect;
import crossmobile.ios.foundation.NSIndexPath;
import crossmobile.ios.uikit.UIBarButtonItem;
import crossmobile.ios.uikit.UIBarButtonSystemItem;
import crossmobile.ios.uikit.UIColor;
import crossmobile.ios.uikit.UIScreen;
import crossmobile.ios.uikit.UITableView;
import crossmobile.ios.uikit.UITableViewCell;
import crossmobile.ios.uikit.UITableViewDataSource;
import crossmobile.ios.uikit.UITableViewStyle;
import crossmobile.ios.uikit.UIView;
import crossmobile.ios.uikit.UIViewController;

import java.util.ArrayList;
import java.util.List;

public class ViewController extends UIViewController {
    float dHeight = UIScreen.mainScreen().bounds().size.height;
    float dWidth = UIScreen.mainScreen().bounds().size.width;
    private final UITableView table = new UITableView(new CGRect(0, 0, dWidth, dHeight), UITableViewStyle.Plain);
    List<Person> phonebook = new ArrayList<>();
    XMLHandler xml;

    @Override
    public void loadView() {
        UIView mainView = new UIView();
        mainView.setBackgroundColor(UIColor.whiteColor());

        xml = new XMLHandler();
        phonebook = xml.parceXML();

        table.setDataSource(new UITableViewDataSource() {

            @Override
            public UITableViewCell cellForRowAtIndexPath(final UITableView table, final NSIndexPath idx) {
                Cell cell = (Cell) table.dequeueReusableCellWithIdentifier("Cell");
                if (cell == null)
                    cell = new Cell(phonebook);
                cell.update(idx.row());
                return cell;
            }

            @Override
            public int numberOfRowsInSection(UITableView table, int section) {
                return phonebook.size();
            }
        });

        mainView.addSubview(table);

        setView(mainView);
    }

    @Override
    public void viewDidAppear(boolean animated) {
        table.reloadData();

    }

    @Override
    public void viewDidLoad() {
        navigationItem().setTitle("PhoneBook");
        UIBarButtonItem add = new UIBarButtonItem(UIBarButtonSystemItem.Add, () -> {
            navigationController().pushViewController(new AddPersonController(), true);
            table.reloadData();
        });
        navigationItem().setRightBarButtonItem(add);
    }

}

Cell.java

package crossmobile.projects.phonebook;

import crossmobile.ios.coregraphics.CGRect;
import crossmobile.ios.uikit.UIApplication;
import crossmobile.ios.uikit.UIButton;
import crossmobile.ios.uikit.UIButtonType;
import crossmobile.ios.uikit.UIColor;
import crossmobile.ios.uikit.UIControl;
import crossmobile.ios.uikit.UIControlDelegate;
import crossmobile.ios.uikit.UIControlEvents;
import crossmobile.ios.uikit.UIEvent;
import crossmobile.ios.uikit.UINavigationController;
import crossmobile.ios.uikit.UITableViewCell;
import crossmobile.ios.uikit.UITableViewCellStyle;

import java.util.List;

public class Cell extends UITableViewCell {

    private final List<Person> phonebook;

    public Cell(List<Person> phonebook) {
        super(UITableViewCellStyle.Default, "Cell");
        this.phonebook = phonebook;
    }

    public void update(final int index) {
        textLabel().setText(phonebook.get(index).getName() + " " + phonebook.get(index).getSurname());
        UIButton cellButton = UIButton.buttonWithType(UIButtonType.Custom);
        cellButton.setFrame(new CGRect(0, 0, 320, 35));
        cellButton.setBackgroundColor(UIColor.clearColor());

        cellButton.addTarget(new UIControlDelegate() {

            @Override
            public void exec(UIControl arg0, UIEvent arg1) {
                ((UINavigationController) UIApplication.sharedApplication().keyWindow().rootViewController()).pushViewController(new PersonController(phonebook.get(index)), true);
            }

        }, UIControlEvents.TouchUpInside);
        contentView().addSubview(cellButton);
    }

}

Person.java

package crossmobile.projects.phonebook;

public class Person {

    private String name;
    private String surname;
    private String phone;

    public Person() {
    }

    public Person(String name, String surname, String phone) {
        this.name = name;
        this.surname = surname;
        this.phone = phone;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSurname() {
        return surname;
    }

    public void setSurname(String surname) {
        this.surname = surname;
    }

    public String getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }

}

PersonController.java

package crossmobile.projects.phonebook;

import crossmobile.ios.coregraphics.CGRect;
import crossmobile.ios.uikit.UIAlertAction;
import crossmobile.ios.uikit.UIAlertActionStyle;
import crossmobile.ios.uikit.UIAlertController;
import crossmobile.ios.uikit.UIAlertControllerStyle;
import crossmobile.ios.uikit.UIBarButtonItem;
import crossmobile.ios.uikit.UIBarButtonItemStyle;
import crossmobile.ios.uikit.UIColor;
import crossmobile.ios.uikit.UILabel;
import crossmobile.ios.uikit.UIScreen;
import crossmobile.ios.uikit.UIView;
import crossmobile.ios.uikit.UIViewController;
import crossmobile.rt.BlockInput;

public class PersonController extends UIViewController {

    private final Person person;
    float dHeight = UIScreen.mainScreen().bounds().size.height;
    float dWidth = UIScreen.mainScreen().bounds().size.width;

    public PersonController(Person person) {
        this.person = person;
    }

    @Override
    public void loadView() {
        UIView view = new UIView();
        view.setBackgroundColor(UIColor.whiteColor());

        UILabel name_label = new UILabel(new CGRect(50, 100, 100, 50));
        name_label.setText("Name :");
        UILabel surname_label = new UILabel(new CGRect(50, 150, 100, 50));
        surname_label.setText("Surname :");
        UILabel phone_label = new UILabel(new CGRect(50, 200, 100, 50));
        phone_label.setText("Phone :");
        UILabel name_text = new UILabel(new CGRect(150, 100, 100, 50));
        name_text.setText(person.getName());
        UILabel surname_text = new UILabel(new CGRect(150, 150, 100, 50));
        surname_text.setText(person.getSurname());
        UILabel phone_text = new UILabel(new CGRect(150, 200, 100, 50));
        phone_text.setText(person.getPhone());

        view.addSubview(name_label);
        view.addSubview(surname_label);
        view.addSubview(phone_label);
        view.addSubview(name_text);
        view.addSubview(surname_text);
        view.addSubview(phone_text);

        setView(view);
    }

    @Override
    public void viewDidLoad() {
        navigationItem().setTitle(person.getName());
        UIBarButtonItem add = new UIBarButtonItem("Delete", UIBarButtonItemStyle.Plain, () -> {

                UIAlertController alert = UIAlertController.alertControllerWithTitle("Warning", "Are u sure?", UIAlertControllerStyle.Alert);
                alert.setMessage("Are u sure?");

                alert.addAction(UIAlertAction.actionWithTitle("Delete", UIAlertActionStyle.Destructive, new BlockInput<UIAlertAction>() {

                    @Override
                    public void exec(UIAlertAction arg0) {
                        ((ViewController) navigationController().viewControllers().get(0)).xml.removeContact(person);
                        navigationController().popViewControllerAnimated(true);
                    }
                }));

                alert.addAction(UIAlertAction.actionWithTitle("Back", UIAlertActionStyle.Cancel, null));
                presentModalViewController(alert, true);

        });

        navigationItem().setRightBarButtonItem(add);
    }

}

AddPersonController.java

package crossmobile.projects.phonebook;

import crossmobile.ios.coregraphics.CGRect;
import crossmobile.ios.uikit.UIBarButtonItem;
import crossmobile.ios.uikit.UIBarButtonItemStyle;
import crossmobile.ios.uikit.UIColor;
import crossmobile.ios.uikit.UIKeyboardType;
import crossmobile.ios.uikit.UILabel;
import crossmobile.ios.uikit.UIReturnKeyType;
import crossmobile.ios.uikit.UIScreen;
import crossmobile.ios.uikit.UITextField;
import crossmobile.ios.uikit.UITextFieldDelegate;
import crossmobile.ios.uikit.UIView;
import crossmobile.ios.uikit.UIViewController;

public class AddPersonController extends UIViewController {

    final UITextField name_text = new UITextField(new CGRect(150, 100, 100, 50));
    final UITextField surname_text = new UITextField(new CGRect(150, 150, 100, 50));
    final UITextField phone_text = new UITextField(new CGRect(150, 200, 140, 50));
    float dHeight = UIScreen.mainScreen().bounds().size.height;
    float dWidth = UIScreen.mainScreen().bounds().size.width;

    @Override
    public void loadView() {
        UIView view = new UIView();
        view.setBackgroundColor(UIColor.whiteColor());

        UILabel name_label = new UILabel(new CGRect(50, 100, 100, 50));
        name_label.setText("Name :");
        UILabel surname_label = new UILabel(new CGRect(50, 150, 100, 50));
        surname_label.setText("Surname :");
        UILabel phone_label = new UILabel(new CGRect(50, 200, 100, 50));
        phone_label.setText("Phone :");

        name_text.setPlaceholder("name");
        name_text.setReturnKeyType(UIReturnKeyType.Next);

        surname_text.setPlaceholder("surname");
        surname_text.setReturnKeyType(UIReturnKeyType.Next);

        phone_text.setPlaceholder("phone");
        phone_text.setKeyboardType(UIKeyboardType.Default);
        phone_text.setReturnKeyType(UIReturnKeyType.Done);

        name_text.setDelegate(new UITextFieldDelegate() {

            public boolean textFieldShouldReturn(UITextField textField) {
                name_text.resignFirstResponder();
                surname_text.becomeFirstResponder();
                return false;
            }
        });

        surname_text.setDelegate(new UITextFieldDelegate() {

            public boolean textFieldShouldReturn(UITextField textField) {
                surname_text.resignFirstResponder();
                phone_text.becomeFirstResponder();
                return false;
            }
        });

        phone_text.setDelegate(new UITextFieldDelegate() {

            public boolean textFieldShouldReturn(UITextField textField) {
                phone_text.resignFirstResponder();
                return true;
            }
        });

        view.addSubview(name_label);
        view.addSubview(surname_label);
        view.addSubview(phone_label);
        view.addSubview(name_text);
        view.addSubview(surname_text);
        view.addSubview(phone_text);

        setView(view);
    }

    @Override
    public void viewDidLoad() {
        name_text.becomeFirstResponder();
        navigationItem().setTitle("Add Contact");
        UIBarButtonItem add = new UIBarButtonItem("Add", UIBarButtonItemStyle.Plain, () -> {
            ((ViewController) navigationController().viewControllers().get(0)).xml.addContact(new Person(name_text.text(), surname_text.text(), phone_text.text()));
            navigationController().popViewControllerAnimated(true);

        });

        navigationItem().setRightBarButtonItem(add, true);
    }

}

XMLHandler.java

package crossmobile.projects.phonebook;

import crossmobile.ios.foundation.NSBundle;
import crossmobile.ios.foundation.NSData;
import crossmobile.ios.foundation.NSXMLParser;
import crossmobile.ios.foundation.NSXMLParserDelegate;

import java.util.List;

public class XMLHandler {

    private final NSXMLParser xmlparser;
    private final ParserDelegate deleg;
    private final String path;
    private List<Person> phonebook;

    public XMLHandler() {
        path = NSBundle.mainBundle().pathForResource("phonebook", "xml");
        System.out.println(path==null?"null":path);
        NSData xmldata = NSData.dataWithContentsOfFile(path);
        xmlparser = new NSXMLParser(xmldata);
        deleg = new ParserDelegate();
        xmlparser.setDelegate((NSXMLParserDelegate) deleg);
    }

    public List<Person> parceXML() {
        xmlparser.parse();
        phonebook = deleg.getPhoneBook();
        return phonebook;
    }

    public List<Person> addContact(Person person) {
        phonebook.add(person);
        return phonebook;
    }

    public List<Person> removeContact(Person person) {
        phonebook.remove(person);

        return phonebook;
    }

}

ParserDelegate.java

package crossmobile.projects.phonebook;

import crossmobile.ios.foundation.NSXMLParser;
import crossmobile.ios.foundation.NSXMLParserDelegate;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

public class ParserDelegate implements NSXMLParserDelegate {

    private final List<Person> phonebook = new ArrayList<>();

    @Override
    public void didStartElement(NSXMLParser parser, String elementName, String namespaceURI, String qualifiedName, Map<String, String> attributes) {
        if (elementName.equals("person")) {
            Person person = null;

            try {
                person = new Person(attributes.get("name"), attributes.get("surname"), attributes.get("phone"));
            } catch (Exception ex) {
            }
            phonebook.add(person);
        }
    }

    public List<Person> getPhoneBook() {
        return phonebook;
    }
}

phonebook.xml

<phonebook>
	<person name="John" surname="Loisios" phone="6934112345"/>
	<person name="Helen" surname="Parliarou" phone="6953548525"/>
	<person name="George" surname="Harris" phone="6912358456"/>
	<person name="Maria" surname="Brown" phone="6945823648"/>
	<person name="Mathiew" surname="Sigovitz" phone="6948521365"/>
	<person name="Henry" surname="Thethird" phone="6914853545"/>
	<person name="Tristana" surname="Yordle" phone="6958732541"/>
	<person name="Mark" surname="Markinson" phone="6958746358"/>
	<person name="Veronika" surname="Mars" phone="6958742146"/>
	<person name="Cloud" surname="Strife" phone="6945218545"/>
	<person name="Crash" surname="Bandicut" phone="6441885455"/>
	<person name="George" surname="Harris" phone="6912358456"/>
	<person name="Maria" surname="Brown" phone="6945823648"/>
	<person name="Mathiew" surname="Sigovitz" phone="6948521365"/>
	<person name="Henry" surname="Thethird" phone="6914853545"/>
	<person name="Tristana" surname="Yordle" phone="6958732541"/>
	<person name="Mark" surname="Markinson" phone="6958746358"/>
	<person name="Veronika" surname="Mars" phone="6958742146"/>
	<person name="Cloud" surname="Strife" phone="6945218545"/>
	<person name="Crash" surname="Bandicut" phone="6441885455"/>
</phonebook>