How to call REST APIs with AlamoFire and Swift

Alamofire is a networking API that leverages the full power of Swift.

Reference:
http://www.raywenderlich.com/85080/beginning-alamofire-tutorial
https://github.com/Alamofire/Alamofire

alamofire

alamofire

Here is sample how to call REST APIs with AlamoFire.

import UIKit
import Alamofire

class ViewController: ViewController {

    var user: [JSON] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()

        Alamofire.request(.GET, "https://api.github.com/users/datomnurdin").responseJSON { (request, response, json, error) in
            if json != nil {
                var jsonObj = JSON(json!)
                if let data = jsonObj["user"].arrayValue as [JSON]?{
                    println(data)
                }
            }
        }
    }
}

Develop a simple to-do-list mobile app using phonegap/cordova for iOS and android -Part 3

This tutorial is the third part of a three-part series on how to create a simple to-do-list app for beginners.

In the first part of the tutorial series, setup development environment using certain IDE for iOS/android and preview your iOS and android hybrid app using emulator and actual device (smart phone). http://blog.revivalx.com/2014/11/02/develop-a-simple-to-do-list-mobile-app-using-phonegapcordova-for-ios-and-android-part-1/

In this second tutorial, you’ll learn how to develop iOS and android hybrid app using client side language and create multi page application for iOS and android hybrid app. http://blog.revivalx.com/2014/11/03/develop-a-simple-to-do-list-mobile-app-using-phonegapcordova-for-ios-and-android-part-2/

In this third tutorial, you will learn how to create a simple web service for your app. Your web service will enable to create, read, update and data using JSON ( Javascript Object Notation) to your database. We will not using SOAP (Simple Object Access Protocol) for this tutorial because JSON is easy to learn and simple compare to SOAP is too complex for beginner. It basically works on HTTP protocol.

URL Structure

In web service design the URL endpoints should be well formed and should be easily understandable. Every URL for a resource should be uniquely identified.

For example

GET – http://localhost:8888/todolist/todo/index
GET – http://localhost:8888/todolist/todo/display?taskId=1
POST – http://localhost:8888/todolist/todo/create
POST – http://localhost:8888/todolist/todo/update?taskId=1
POST – http://localhost:8888/todolist/todo/delete?taskId=1

Why we using JSON for mobile application? Why not we access directly to our database without using JSON instead PHP or JAVA. It is because hybrid mobile app support client side languages, not servers side languages. Hybrid mobile app consists these 3 languages are HTML5, CSS and Javascript. We can’t simply run PHP or JAVA in mobile app. This video (http://coenraets.org/blog/2013/05/architecting-a-phonegap-application-video-slides/) will answer these questions.

Getting started.

For this tutorial you need to have basic in PHP and Mysql. You need to have eclipse Helios (https://www.eclipse.org/downloads/packages/eclipse-ide-java-ee-developers/heliossr2 ) to complete the project. Compare to previous tutorial we using eclipse Juno. It is because we develop an android app. For eclipse PHP we develop web service using PHP.

First you need to setup a web server in your machine. I’m using MAMP (stands for Mac, Apache, Mysql and Php) for this tutorial. It’s ok if your want to use other than this such as XAMPP or WAMP. No problem with that. But i suggest you using MAMP if you using Mac. There will be a lot of glitches if you using XAMPP or WAMP in your apple machine.

MAMP – http://www.mamp.info/en/downloads/

XAMPP – https://www.apachefriends.org/download.html

WAMP – http://www.wampserver.com/en/

Download MAMP and install to your machine. After finish installed MAMP to your machine, start apache server and mysql server. So far I didn’t get any issues starting my web server compare to XAMPP. If you got problem start up your apache server, make sure you check port 80 because maybe other applications using the same port especially skype. you need to terminate the application before start the apache server. This issue always happened to windows users.

If your apache and mysql server running successful, you will get like this (green light on both server status).

MAMP

MAMP

Then open your chrome browser. Why I’m using chrome rather than other browser because there are a tons of chrome extensions available in chrome marketplace. That’s why i choose to live with it. Type this to open your MAMP start page in your browser.

http://localhost:8888/MAMP/?language=English

Then click phpMyAdmin at top of the bar. You will see this page.

phpmyadmin

phpmyadmin

You need to create a database and a table for this tutorial. Click database tab. Then create ‘todolist‘. Copy this sql script to your sql tab to generate task table.

CREATE TABLE `tasks` (
`taskId` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(250) NOT NULL,
`description` varchar(500) NOT NULL,
`dateCreated` datetime NOT NULL,
`dateUpdated` datetime NOT NULL,
PRIMARY KEY (`taskId`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

After executing these queries go through each tables and make sure that everything created correctly. Until now we are done with getting your system ready for development. Run your eclipse Helios to start develop web service. Right click in PHP explore > New > PHP Project.

eclipe helios

eclipe helios

Type todolist-api in project name. At content part, choose create project at existing location (from existing source). Type path name in directory field. /Applications/MAMP/htdocs/todolist-api  . Click Finish.

Right click in your project, select New > PHP File .

PHP File

PHP File

Type db_config.php and click Finish.

You need to create 5 more php files for db_connect.php, create_task.php, get_task_details.php, get_all_tasks.php, update_task.php and delete_task.php. You can check reference that I take from this site for this tutorial.

db_config.php – database configuration / setting.

db_connect.php – database connection.

create_task.php – create task details into database.

get_task_tasks.php – get task details base on task id from database.

get_all_tasks – retrieve all list of tasks.

update_task.php – update task into database base on task id.

delete_task.php – delete task from database base on task id.

Fill up all these PHP files using these code.

db_config.php

<?php
define('DB_USER', "root"); // db user
define('DB_PASSWORD', "root"); // db password (mention your db password here)
define('DB_DATABASE', "todolist"); // database name
define('DB_SERVER', "localhost"); // db server
?>

db_connect.php

<?php
class DB_CONNECT {

    // constructor
    function __construct() {
        // connecting to database
        $this->connect();
    }

    // destructor
    function __destruct() {
        // closing db connection
        $this->close();
    }

    /**
     * Function to connect with database
     */
    function connect() {
        // import database connection variables
        require_once __DIR__ . '/db_config.php';

        // Connecting to mysql database
        $con = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD) or die(mysql_error());

        // Selecing database
        $db = mysql_select_db(DB_DATABASE) or die(mysql_error()) or die(mysql_error());

        // returing connection cursor
        return $con;
    }

    /**
     * Function to close db connection
     */
    function close() {
        // closing db connection
        mysql_close();
    }

}

?>

create_task.php

<?php

/*
 * Following code will create a new task row
 * All task details are read from HTTP Post Request
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['name']) && isset($_POST['description'])) {

    $name = $_POST['name'];
    $description = $_POST['description'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql inserting a new row
    $result = mysql_query("INSERT INTO tasks(name, description, dateCreated, dateUpdated) VALUES('$name', '$description', NOW(), NOW())");

    // check if row inserted or not
    if ($result) {
        // successfully inserted into database
        $response["success"] = 1;
        $response["message"] = "Task successfully created.";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // failed to insert row
        $response["success"] = 0;
        $response["message"] = "Oops! An error occurred.";

        // echoing JSON response
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

get_task_details.php

<?php

/*
 * Following code will get single task details
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// check for post data
if (isset($_GET["taskId"])) {
    $taskId = $_GET['taskId'];

    // get a task from task table
    $result = mysql_query("SELECT *FROM tasks WHERE taskId = $taskId");

    if (!empty($result)) {
        // check for empty result
        if (mysql_num_rows($result) > 0) {

            $result = mysql_fetch_array($result);

            $task = array();
            $task["taskId"] = $result["taskId"];
            $task["name"] = $result["name"];
            $task["description"] = $result["description"];
            $task["dateCreated"] = $result["dateCreated"];
            $task["dateUpdated"] = $result["dateUpdated"];
            // success
            $response["success"] = 1;

            // task node
            $response["task"] = array();

            array_push($response["task"], $task);

            // echoing JSON response
            echo json_encode($response);
        } else {
            // no task found
            $response["success"] = 0;
            $response["message"] = "No task found";

            // echo no tasks JSON
            echo json_encode($response);
        }
    } else {
        // no task found
        $response["success"] = 0;
        $response["message"] = "No task found";

        // echo no tasks JSON
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

get_all_tasks.php

<?php

/*
 * Following code will list all the tasks
 */

// array for JSON response
$response = array();

// include db connect class
require_once __DIR__ . '/db_connect.php';

// connecting to db
$db = new DB_CONNECT();

// get all tasks from task table
$result = mysql_query("SELECT *FROM tasks") or die(mysql_error());

// check for empty result
if (mysql_num_rows($result) > 0) {
    // looping through all results
    // tasks node
    $response["tasks"] = array();

    while ($row = mysql_fetch_array($result)) {
        // temp tasks array
        $tasks = array();
        $task["taskId"] = $row["taskId"];
        $task["name"] = $row["name"];
        $task["description"] = $row["description"];
        $task["dateCreated"] = $row["dateCreated"];
        $task["dateUpdated"] = $row["dateUpdated"];

        // push single task into final response array
        array_push($response["tasks"], $task);
    }
    // success
    $response["success"] = 1;

    // echoing JSON response
    echo json_encode($response);
} else {
    // no tasks found
    $response["success"] = 0;
    $response["message"] = "No tasks found";

    // echo no tasks JSON
    echo json_encode($response);
}
?>

update_task.php

<?php

/*
 * Following code will update a task information
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['taskId']) && isset($_POST['name']) && isset($_POST['description'])) {

    $taskId = $_POST['taskId'];
    $name = $_POST['name'];
    $description = $_POST['description'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql update row with matched pid
    $result = mysql_query("UPDATE tasks SET name = '$name', description = '$description', dateUpdated = NOW() WHERE taskId = $taskId");

    // check if row inserted or not
    if ($result) {
        // successfully updated
        $response["success"] = 1;
        $response["message"] = "Task successfully updated.";

        // echoing JSON response
        echo json_encode($response);
    } else {

    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

delete_task.php

<?php

/*
 * Following code will delete a task from table
 * A task is identified by task id (taskId)
 */

// array for JSON response
$response = array();

// check for required fields
if (isset($_POST['taskId'])) {
    $taskId = $_POST['taskId'];

    // include db connect class
    require_once __DIR__ . '/db_connect.php';

    // connecting to db
    $db = new DB_CONNECT();

    // mysql update row with matched taskId
    $result = mysql_query("DELETE FROM tasks WHERE taskId = $taskId");

    // check if row deleted or not
    if (mysql_affected_rows() > 0) {
        // successfully updated
        $response["success"] = 1;
        $response["message"] = "Task successfully deleted";

        // echoing JSON response
        echo json_encode($response);
    } else {
        // no task found
        $response["success"] = 0;
        $response["message"] = "No task found";

        // echo no tasks JSON
        echo json_encode($response);
    }
} else {
    // required field is missing
    $response["success"] = 0;
    $response["message"] = "Required field(s) is missing";

    // echoing JSON response
    echo json_encode($response);
}
?>

After you fill up the files, you need to install Curl in your machine. Curl is a command line tool for transferring data with URL syntax. Install curl via npm. Type this command to install. If you using windows, run this command in your command prompt.

npm install curl
npm install curl

npm install curl

npm install curl

npm install curl

Run this command to test create_task.php in your terminal.

curl POST

curl POST

Success status for create_task.php

{"success":1,"message":"Task successfully created."}

Run it again twice using different data.

Proceed all these curl commands for each URLs

get_task_details.php

curl http://localhost:8888/todolist-api/get_task_details.php?taskId=1

Success status for get_task_details.php

{
	"success": 1,
	"task": [{
		"taskId": "1",
		"name": "Breakfast",
		"description": "Nasi Lemak",
		"dateCreated": "2014-11-07 01:48:32",
		"dateUpdated": "2014-11-07 01:48:32"
	}]
}

get_all_tasks.php

curl http://localhost:8888/todolist-api/get_all_tasks.php

Success status for get_all_tasks.php

{
	"tasks": [{
		"taskId": "1",
		"name": "Breakfast",
		"description": "Nasi Lemak",
		"dateCreated": "2014-11-07 01:48:32",
		"dateUpdated": "2014-11-07 01:48:32"
	}, {
		"taskId": "2",
		"name": "Afternoon",
		"description": "Nasi Kukus",
		"dateCreated": "2014-11-07 01:53:14",
		"dateUpdated": "2014-11-07 01:53:14"
	}, {
		"taskId": "3",
		"name": "Dinner",
		"description": "Nasi Goreng",
		"dateCreated": "2014-11-07 01:53:31",
		"dateUpdated": "2014-11-07 01:53:31"
	}],
	"success": 1
}

update_task.php

curl -X POST -F taskId=1 -F name=Supper -F description=KFC http://localhost:8888/todolist-api/update_task.php

Success status for update_task.php

{"success":1,"message":"Task successfully updated."}

delete_task.php

curl -X POST -F taskId=1 http://localhost:8888/todolist-api/delete_task.php

Success status for delete_task.php

{"success":1,"message":"Task successfully deleted"}

Now we want to integrate PHP with the app. You need to replace all html files and js files so we can invoke PHP from there.

AddPage.js

currentPage = {};
currentPage.init = function() {
    console.log("AddPage :: init");
};
currentPage.back = function() {
    console.log("AddPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.add = function() {
    console.log("AddPage :: add");
    var name = $("#name").val();
    var description = $("#description").val();
    formData = {
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/create_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Add task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Add task failure");
            }
        });
    }
};

DetailPage.js

currentPage = {};
currentPage.init = function() {
    console.log("DetailPage :: init");
    detailTask();
};
currentPage.back = function() {
    console.log("DetailPage :: back");
    $("body").load(path + "pages/ListPage.html", function() {
        $.getScript(path + "js/ListPage.js", function() {
            if (currentPage.init) {
                currentPage.init();
            }
        });
    });
};
currentPage.edit = function() {
    console.log("DetailPage :: edit");
    var taskId = sessionStorage.taskId;
    var name = $("#name").val();
    var description = $("#description").val();
    formData = {
        taskId: sessionStorage.taskId,
        name: $("#name").val(),
        description: $("#description").val()
    }
    if (name == "") {
        alert("Please enter name");
    } else if (description == "") {
        alert("Please enter description");
    } else {
        $.ajax({
            type: "post",
            url: "http://demo.revivalx.com/todolist-api/update_task.php",
            data: formData,
            dataType: "json",
            success: function(data) {
                alert("Edit task success");
                $("body").load(path + "pages/ListPage.html", function() {
                    $.getScript(path + "js/ListPage.js", function() {
                        if (currentPage.init) {
                            currentPage.init();
                        }
                    });
                });
            },
            error: function() {
                alert("Edit task failure");
            }
        });
    }
};

function detailTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_task_details.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            $('#name').val(data.task[0].name);
            $('#description').val(data.task[0].description);
        },
        error: function() {
            alert("Detail task failure");
        }
    });
}
currentPage.remove = function() {
    console.log("DetailPage :: delete");
    deleteTask();
};

function deleteTask() {
    formData = {
        taskId: sessionStorage.taskId
    }
    $.ajax({
        type: "post",
        url: "http://demo.revivalx.com/todolist-api/delete_task.php",
        data: formData,
        dataType: "json",
        success: function(data) {
            alert("Delete task success");
            $("body").load(path + "pages/ListPage.html", function() {
                $.getScript(path + "js/ListPage.js", function() {
                    if (currentPage.init) {
                        currentPage.init();
                    }
                });
            });
        },
        error: function() {
            alert("Delete task failure");
        }
    });
}

ListPage.js

currentPage = {};
currentPage.init = function() {
    console.log("ListPage :: init");
    listTasks();
};
currentPage.loadPage = function(pageIndex) {
    console.log("ListPage :: loadPage :: pageIndex: " + pageIndex);
    $("body").load(path + "pages/" + pageIndex + ".html");
    $.getScript(path + "js/" + pageIndex + ".js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};
currentPage.detailPage = function(taskId) {
    sessionStorage.setItem("taskId", taskId);
    $("body").load(path + "pages/DetailPage.html");
    $.getScript(path + "js/DetailPage.js", function() {
        if (currentPage.init) {
            currentPage.init();
        }
    });
};

function listTasks() {
    $.ajax({
        type: "get",
        url: "http://demo.revivalx.com/todolist-api/get_all_tasks.php",
        dataType: "json",
        success: function(data) {
            var ul = $('#taskList');
            var html = '';
            $.each(data.tasks, function(index, item) {
                html += '<li class="table-view-cell">';
                html += '<a class="navigate-right" onclick="currentPage.detailPage(' + item.taskId + ');" >';
                html += item.name;
                html += '</a></li>';
            });
            ul.append(html);
        },
        error: function() {
            alert("List task failure");
        }
    });
}

AddPage.html

<script>
    $.getScript(path + "js/AddPage.js");
</script>
  
<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
    <h1 class="title">AddPage</h1>
</header>
<div class="content">
	<div class="card">
    <ul class="table-view">
        <li class="table-view-cell table-view-divider">Name:</li>
 
        <li class="table-view-cell"><input id="name" name="name" type="text"></li>
 
        <li class="table-view-cell table-view-divider">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" type="text"></li>
 
        <li class="table-view-cell"></li>
    </ul>
   </div>
    <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.add();">ADD TASK</button>
    </div>
</div>

DetailPage.html

<script>
    $.getScript(path + "js/DetailPage.js");
</script>
 
<header class="bar bar-nav">
    <a class="icon icon-left-nav pull-left" onclick="currentPage.back();"></a>
    <h1 class="title">DetailPage</h1>
</header>
 
<div class="content">
	<div class="card">
    <ul class="table-view">
        <li class="table-view-cell table-view-divider">Name:</li>
 
        <li class="table-view-cell"><input id="name" name="name" type="text"></li>
 
        <li class="table-view-cell table-view-divider">Description:</li>
 
        <li class="table-view-cell"><input id="description" name="description" type="text"></li>
 
    </ul>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-positive btn-block" onclick="currentPage.edit();">EDIT TASK</button>
   </div>
   <div class="card" style="margin-bottom:40px;">
    	<button class="btn btn-negative btn-block" onclick="currentPage.remove();">REMOVE TASK</button>
   </div> 
</div>

ListPage.html

<script>
    $.getScript(path + "js/ListPage.js");
</script>

<header class="bar bar-nav">
	<button id="LoadAddButton" class="btn pull-right" onclick="currentPage.loadPage('AddPage');">Add</button>
  	<h1 class="title">ListPage</h1>
</header>

<div class="content">
	<ul id="taskList" class="table-view"></ul>
</div>

Build and run your app. You can find the source code here: https://github.com/datomnurdin/com.revivalx.cordova.todomobile

Simple app (CRUD) using IBM worklight 6.1

Getting started with IBM Worklight V6.1. This tutorial show you how to do simple CRUD operation using IBM Worklight. What you need for this tutorial are

Outline that cover for this tutorial:

  • Setting up your development environment
  • Preview your app
  • Learning Worklight client side API
  • Building a multi page application
  • Learning Worklight server side API

Setting up your development environment

Step 1

Visit this link to install worklight into your eclipse.

http://blog.revivalx.com/2014/05/22/ibm-worklight-installation-on-eclipse/

Open up your eclipse. Go to File > New > Other.

eclipse new project

eclipse new project

Step 2

Choose Worklight Project. Click Next.

select wizard

select wizard

Step 3

Type CRUD-worklight or your own project name in name textbox. Click Next.

new worklight project

new worklight project

Step 4

Type CRUDWorklight or your own for application name. Click Finish. A popup will show up. Tick Remember my decision and click Yes.

open associated perspective

open associated perspective

Step 5

Open application-descriptor.xml.

application descriptor

application descriptor

Step 6

Click Source tab at bottom of page.

application descriptor

application descriptor

Step 7

Change author details. (optional).

application descriptor

application descriptor

Step 8

Right click worklight project , go to New > Worklight Environment. This part is when we want to add platform into our worklight project such as iOS, android and windows mobile.

worklight environment

worklight environment

Step 9

Select your project and application/component. For this tutorial I will cover only for iOS and android. For windows mobile you need a windows machine to run the project using Visual Studio Express in Windows 8.1 operating system. Tick iphone and android phones and tablets. Click Finish.

worklight environment

worklight environment

Step 10

Your project directory will be like this.

worklight directory

worklight directory

Preview your app (android)

Step 11

import android project

import android project

Step 12

Select Existing Android Code Into Workspace. Click Next.

import android project

import android project

Step 13

Click Browse to select android project.

import android project

import android project

Step 14

Browse your project and click Open.

import android project

import android project

Step 15

Click Finish.

import android project

import android project

Step 16

Follow this tutorial how to run android app in android simulator.

http://blog.revivalx.com/2014/02/21/crud-operation-using-jquery-mobile-on-android-part-1/

Preview your app (iOS)

Step 17

Right click on iphone folder and go to Run AsXcode Project.

Run As Xcode Project

Run As Xcode Project

 

Step 18

Click Play on top left side to preview the app on your iphone.

xcode5

xcode5

Learning Worklight client side API and Building a multi page application

Step 19

Right click js folder inside common folder in your worklight project. Go to New > Javascript Source File.

Javascript Source File

Javascript Source File

Step 20

Create 3 javascript files.

  • AddPage.js – to add user details.
  • ListPage.js – to retrieve user list.
  • DetailPage.js – to retrieve user details.

Click Finish.

new javascript file

new javascript file

Step 21

You latest project directory will be like this.

Step 22

Right click common folder and go to New > Folder to create a new folder.

add folder

add folder

Step 23

Then create a few of html pages inside page folder that we already created just now. Right click pages folder and go to New > HTML File.

HTML Files

HTML Files

Step 24

Create 3 html files.

  • AddPage.html – to add user details.
  • ListPage.html – to retrieve user list.
  • DetailPage.html – to retrieve user details.
new html file

new html file

Step 25

You latest project directory will be like this for html files.

new html files

new html files

Step 26

Open your main.css file and replace with this code.

a, abbr, address, article, aside, audio, b, blockquote, body, canvas, caption, cite, code, dd, del, details, dfn, dialog, div, dl, dt, em, fieldset, figcaption, figure, footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, html, i, iframe, img, ins, kbd, label, legend, li, mark, menu, nav, object, ol, p, pre, q, samp, section, small, span, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, time, tr, ul, var, video {
margin: 0;
padding: 0;
}

/* Worklight container div */
body {
min-height: 460px;
margin: 0 auto;
/*width: 320px;*/
}

h1 {
font-size: 18px;
}

#AppBody {
min-height: 460px;
margin: 0 auto;
/*width: 320px;*/
background-color: #ccc;
overflow: hidden;
overflow-y: auto;
}

#header {
text-align: center;
background-color: #1D4D90;
color: #F9FAFB;
font-size: 16px;
height: 38px;
line-height: 38px;
border-bottom: 1px solid #BBBBBB;
}

#wrapper {
padding: 10px;
}

p{
padding: 10px;
}

#itemsList{
margin-top: 38px;
}

#itemsList li {
border-bottom: 1px solid #bbb;
min-height: 40px;
padding: 0 25px 0 15px;
cursor: pointer;
}

#itemsList li .pubDate {
color: #555;
font-size: 10px;
font-family: Arial;
}

#itemsList li:hover {
background-color: #EFEFEF;
}
replace main.css

replace main.css

Step 27

Open your index.html and replace with this code.

<!DOCTYPE HTML>
<html>
    	<head>
    		<meta charset="UTF-8">
    		<title>index</title>
    		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">
    		<link rel="shortcut icon" href="images/favicon.png">
    		<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
    		<link rel="stylesheet" href="css/main.css">
    		<script>window.$ = window.jQuery = WLJQ;</script>
    	</head>
    	<body style="display: none;">
    		<div id="AppBody">
				<!-- This is static header, it will be shown always -->
				<div id="header">
					<h1>CRUD Worklight</h1>
				</div>		

				<!-- This is a placeholder for dynamic page content -->
				<div id="pagePort"></div>
			</div>
    		<script src="js/initOptions.js"></script>
    		<script src="js/main.js"></script>
    		<script src="js/messages.js"></script>
    	</body>
</html>
replace index.html

replace index.html

Step 28

Replace all codes with given codes for each javascript files.

AddPage.js

currentPage={};

currentPage.init = function() {
	WL.Logger.debug("AddPage :: init");
};

currentPage.back = function(){
	WL.Logger.debug("AddPage :: back");
	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});
};

DetailPage.js

currentPage={};

currentPage.init = function() {
	WL.Logger.debug("DetailPage :: init");
	detailUser();
};

currentPage.back = function(){
	WL.Logger.debug("DetailPage :: back");
	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});
};

ListPage.js

currentPage = {};
var busyIndicator = null;

currentPage.init = function(){
	WL.Logger.debug("ListPage :: init");
	busyIndicator = new WL.BusyIndicator('AppBody');
	listUsers();
};

currentPage.loadPage = function(pageIndex){
	WL.Logger.debug("ListPage :: loadPage :: pageIndex: " + pageIndex);
	$("#pagePort").load(path + "pages/" + pageIndex + ".html");
	$.getScript(path + "js/" + pageIndex +".js", function() {
		if (currentPage.init) {
			currentPage.init();
		}
	});
};

main.js

var pagesHistory = [];
var currentPage = {};
var path = "";

function wlCommonInit(){
	// Special case for Windows Phone 8 only.
	if (WL.Client.getEnvironment() == WL.Environment.WINDOWS_PHONE_8) {
	    path = "www/default/";
	}

	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});

}
replace javascript files

replace javascript files

Step 29

Replace all codes with given codes for each html files.

AddPage.html

<script>
 	$.getScript(path + "js/AddPage.js");
</script>
<p>
	Currently <b>AddPage.html</b> page is loaded.
</p>

<input type="button" value="BACK" onclick="currentPage.back();" />

DetailPage.html

<script>
 	$.getScript(path + "js/DetailPage.js");
</script>
<p>
	Currently <b>DetailPage.html</b> page is loaded.
</p>

<input type="button" value="BACK" onclick="currentPage.back();" />

ListPage.html

<script>
	$.getScript(path + "js/ListPage.js");
</script>
<p>
	Currently <b>ListPage.html</b> page is loaded.
</p>
<input type="button" value="Load Add.html" id="LoadAddButton" onclick="currentPage.loadPage('AddPage');" />
<input type="button" value="Load Detail.html" id="LoadAddButton" onclick="currentPage.loadPage('DetailPage');" />
replace html files

replace html files

Step 30

Right click on CRUDWorklight folder > Run As > Build All Environments.

Build All Environments

Build All Environments

Step 31

Repeat step 16 (android) and step 17-19 (iOS) to preview your app.

Step 32

Now we create a worklight adapter for this project. Right click worklight project and go to New > Worklight Adapter.

worklight adapter

worklight adapter

Step 33

Select project and adapter type. Enter your adapter name. USERAdapter. Click Finish.

worklight adapter

worklight adapter

Step 34

You latest project directory will be like this for worklight adapter.

worklight adapter

worklight adapter

Step 35

Open USERAdapter.xml and click source tab at bottom of the page.

worklight adapter

worklight adapter

Step 36

We will using there URLs for our HTTP request/response. Refer to this tutorial for more understanding.

Replace code inside USERAdapter.xml and USERAdapter-impl.js .

USERAdapter.xml

<?xml version="1.0" encoding="UTF-8"?>
<!--
    Licensed Materials - Property of IBM
    5725-I43 (C) Copyright IBM Corp. 2011, 2013. All Rights Reserved.
    US Government Users Restricted Rights - Use, duplication or
    disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
-->
<wl:adapter name="USERAdapter"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:wl="http://www.worklight.com/integration"
	xmlns:http="http://www.worklight.com/integration/http">

	<displayName>USERAdapter</displayName>
	<description>USERAdapter</description>
	<connectivity>
		<connectionPolicy xsi:type="http:HTTPConnectionPolicyType">
			<protocol>http</protocol>
			<domain>demo.revivalx.com</domain>
			<port>80</port>
			<!-- Following properties used by adapter's key manager for choosing specific certificate from key store
			<sslCertificateAlias></sslCertificateAlias>
			<sslCertificatePassword></sslCertificatePassword>
			-->
		</connectionPolicy>
		<loadConstraints maxConcurrentConnectionsPerNode="2" />
	</connectivity>

	<procedure name="listUsers"/>
	<procedure name="addUser"/>
	<procedure name="detailUser"/>
	<procedure name="editUser"/>
	<procedure name="deleteUser"/>

</wl:adapter>

USERAdapter-impl.js

function listUsers() {

	var input = {
		    method : 'get',
		    returnedContentType : 'json',
		    path : "worklight/get_all_users.php"
		};

	return WL.Server.invokeHttp(input);
}

function addUser(name,officeNumber,phoneNumber,email) {

	var input = {
		    method : 'get',
		    returnedContentType : 'json',
		    path : "worklight/create_user.php",
		    parameters : {
		    	name:name,
		    	officeNumber:officeNumber,
		    	phoneNumber:phoneNumber,
		    	email:email
		    }
		};

	return WL.Server.invokeHttp(input);
}

function detailUser(userId) {
	var userIdS = userId.toString();
	var input = {
		    method : 'get',
		    returnedContentType : 'json',
		    path : "worklight/get_user_details.php",
		    parameters : {
		    	userId:userIdS
		    }
		};

	return WL.Server.invokeHttp(input);
}

function editUser(userId,name,officeNumber,phoneNumber,email) {
	var userIdS = userId.toString();
	var input = {
		    method : 'get',
		    returnedContentType : 'json',
		    path : "worklight/update_user.php",
		    parameters : {
		    	userId:userIdS,
		    	name:name,
		    	officeNumber:officeNumber,
		    	phoneNumber:phoneNumber,
		    	email:email
		    }
		};

	return WL.Server.invokeHttp(input);
}

function deleteUser(userId) {
	var userIdS = userId.toString();
	var input = {
		    method : 'get',
		    returnedContentType : 'json',
		    path : "worklight/delete_user.php",
		    parameters : {
		    	userId:userIdS
		    }
		};

	return WL.Server.invokeHttp(input);
}

Step 37

Now we deploy worklight adapter and invoke it.

Deploy Worklight Adapter

Deploy Worklight Adapter

Step 38

Right click on USERAdapter and go to Run As > Invoke Worklight Procedure.

Invoke Worklight Procedure

Invoke Worklight Procedure

Step 39

Select getUsers procedure and Click Run.

Invoke Worklight Procedure

Invoke Worklight Procedure

Step 40

Below is result from http header after we invoke worklight adapter.

Invoke Worklight Procedure

Invoke Worklight Procedure

Step 41

Now we want to integrate worklight adapter with app. You need to replace all html files and js files so we can invoke worklight adapter from there.

AddPage.js

currentPage={};

currentPage.init = function() {
	WL.Logger.debug("AddPage :: init");
};

currentPage.back = function(){
	WL.Logger.debug("AddPage :: back");
	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});
};

currentPage.add = function(){
	WL.Logger.debug("AddPage :: add");
	busyIndicator = new WL.BusyIndicator('AppBody');
	var name = $("#name").val();
	var officeNumber = $("#officeNumber").val();
	var phoneNumber = $("#phoneNumber").val();
	var email = $("#email").val();
	if(name == ""){
		WL.SimpleDialog.show("Alert","Please enter name",[{text:'OK'}]);
	} else if(officeNumber == ""){
		WL.SimpleDialog.show("Alert","Please enter office number",[{text:'OK'}]);
	} else if(phoneNumber == ""){
		WL.SimpleDialog.show("Alert","Please enter phone number",[{text:'OK'}]);
	} else if(email == ""){
		WL.SimpleDialog.show("Alert","Please enter email",[{text:'OK'}]);
	} else{
		createUser(name,officeNumber,phoneNumber,email);
	}
};

function createUser(name,officeNumber,phoneNumber,email){
	busyIndicator.show();
	var invocationData = {
			adapter : 'USERAdapter',
			procedure : 'addUser',
			parameters : [name,officeNumber,phoneNumber,email]
		};

	WL.Client.invokeProcedure(invocationData,{
		onSuccess : addUserSuccess,
		onFailure : addUserFailure
	});
}

function addUserSuccess(result){
	WL.Logger.debug("Add user success");
	WL.SimpleDialog.show("Success","Add user success",[{text:'OK'}]);
	busyIndicator.hide();
	currentPage.back();
}

function addUserFailure(result){
	WL.Logger.error("Add user failure");
	busyIndicator.hide();
}

DetailPage.js

currentPage={};

currentPage.init = function() {
	WL.Logger.debug("DetailPage :: init");
	detailUser();
};

currentPage.back = function(){
	WL.Logger.debug("DetailPage :: back");
	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});
};

currentPage.edit = function() {
	WL.Logger.debug("DetailPage :: edit");
	busyIndicator = new WL.BusyIndicator('AppBody');

	var userId = sessionStorage.userId;
	var name = $("#name").val();
	var officeNumber = $("#officeNumber").val();
	var phoneNumber = $("#phoneNumber").val();
	var email = $("#email").val();
	if(name == ""){
		WL.SimpleDialog.show("Alert","Please enter name",[{text:'OK'}]);
	} else if(officeNumber == ""){
		WL.SimpleDialog.show("Alert","Please enter office number",[{text:'OK'}]);
	} else if(phoneNumber == ""){
		WL.SimpleDialog.show("Alert","Please enter phone number",[{text:'OK'}]);
	} else if(email == ""){
		WL.SimpleDialog.show("Alert","Please enter email",[{text:'OK'}]);
	} else{
		editUser(userId,name,officeNumber,phoneNumber,email);
	}

};

currentPage.remove = function() {
	WL.Logger.debug("DetailPage :: delete");
	busyIndicator = new WL.BusyIndicator('AppBody');
	deleteUser();
};

function detailUser(){
	var userId = sessionStorage.userId;
	busyIndicator.show();
	var invocationData = {
			adapter : 'USERAdapter',
			procedure : 'detailUser',
			parameters : [userId]
		};

	WL.Client.invokeProcedure(invocationData,{
		onSuccess : detailUserSuccess,
		onFailure : detailUserFailure
	});
}

function detailUserSuccess(result){
	WL.Logger.debug("Detail retrieve success");
	busyIndicator.hide();
	if (result.invocationResult.user.length>0) {
		displayUsers(result.invocationResult.user);
	} 

	else
		detailUserFailure();
}

function detailUserFailure(result){
	WL.Logger.error("Detail retrieve failure");
	busyIndicator.hide();
	WL.SimpleDialog.show("CRUD Worklight", "Cannot retrieve detail. Please check your internet connectivity.",
	[{
		text : 'Reload App',
		handler : WL.Client.reloadApp
	}]);
}

function displayUsers(user){
	$('#name').val(user[0].name);
	$('#officeNumber').val(user[0].officeNumber);
	$('#phoneNumber').val(user[0].phoneNumber);
	$('#email').val(user[0].email);
}

function editUser(userId,name,officeNumber,phoneNumber,email){
	busyIndicator.show();
	var invocationData = {
			adapter : 'USERAdapter',
			procedure : 'editUser',
			parameters : [userId,name,officeNumber,phoneNumber,email]
		};

	WL.Client.invokeProcedure(invocationData,{
		onSuccess : editUserSuccess,
		onFailure : editUserFailure
	});
}

function editUserSuccess(result){
	WL.Logger.debug("Edit success");
	busyIndicator.hide();
	WL.SimpleDialog.show("Success","Edit user success",[{text:'OK'}]);
	busyIndicator.hide();
	currentPage.back();
}

function editUserFailure(result){
	WL.Logger.error("Edit failure");
	busyIndicator.hide();
	WL.SimpleDialog.show("CRUD Worklight", "Cannot edit. Please check your internet connectivity.",
	[{
		text : 'Reload App',
		handler : WL.Client.reloadApp
	}]);
}

function deleteUser(){
	var userId = sessionStorage.userId;
	busyIndicator.show();
	var invocationData = {
			adapter : 'USERAdapter',
			procedure : 'deleteUser',
			parameters : [userId]
		};

	WL.Client.invokeProcedure(invocationData,{
		onSuccess : deleteUserSuccess,
		onFailure : deleteUserFailure
	});
}

function deleteUserSuccess(result){
	WL.Logger.debug("Detail retrieve success");
	busyIndicator.hide();
	WL.SimpleDialog.show("Success","Delete user success",[{text:'OK'}]);
	busyIndicator.hide();
	currentPage.back();
}

function deleteUserFailure(result){
	WL.Logger.error("Delete failure");
	busyIndicator.hide();
	WL.SimpleDialog.show("CRUD Worklight", "Cannot delete. Please check your internet connectivity.",
	[{
		text : 'Reload App',
		handler : WL.Client.reloadApp
	}]);
}

ListPage.js

currentPage = {};
var busyIndicator = null;

currentPage.init = function(){
	WL.Logger.debug("ListPage :: init");
	busyIndicator = new WL.BusyIndicator('AppBody');
	listUsers();
};

currentPage.loadPage = function(pageIndex){
	WL.Logger.debug("ListPage :: loadPage :: pageIndex: " + pageIndex);
	$("#pagePort").load(path + "pages/" + pageIndex + ".html");
	$.getScript(path + "js/" + pageIndex +".js", function() {
		if (currentPage.init) {
			currentPage.init();
		}
	});
};

currentPage.detailPage = function(userId){
	sessionStorage.setItem("userId", userId);
	$("#pagePort").load(path + "pages/DetailPage.html");
	$.getScript(path + "js/DetailPage.js", function() {
		if (currentPage.init) {
			currentPage.init();
		}
	});
};

function listUsers(){
	busyIndicator.show();
	var invocationData = {
			adapter : 'USERAdapter',
			procedure : 'listUsers',
			parameters : []
		};

	WL.Client.invokeProcedure(invocationData,{
		onSuccess : listUsersSuccess,
		onFailure : listUsersFailure
	});
}

function listUsersSuccess(result){
	WL.Logger.debug("List retrieve success");
	busyIndicator.hide();
	if (result.invocationResult.users.length>0) {
		displayUsers(result.invocationResult.users);
	} 

	else
		listUsersFailure();
}

function listUsersFailure(result){
	WL.Logger.error("List retrieve failure");
	busyIndicator.hide();
	WL.SimpleDialog.show("CRUD Worklight", "Cannot retrieve list. Please check your internet connectivity.",
	[{
		text : 'Reload App',
		handler : WL.Client.reloadApp
	}]);
}

function displayUsers(users){
	var ul = $('#itemsList');
	var html ='';
	$.each(users, function(index, item) {
		html += '<li><a onclick="currentPage.detailPage('+item.userId+');" >';
		html += '<h4>' + item.name + '</h4>';
		html += '<p>' + item.email + '</p>';
		html += '</a></li>';

	});

	ul.append(html);
}

Main.js

var pagesHistory = [];
var currentPage = {};
var path = "";

function wlCommonInit(){
	// Special case for Windows Phone 8 only.
	if (WL.Client.getEnvironment() == WL.Environment.WINDOWS_PHONE_8) {
	    path = "www/default/";
	}

	$("#pagePort").load(path + "pages/ListPage.html", function(){
		$.getScript(path + "js/ListPage.js", function() {
			if (currentPage.init) {
				currentPage.init();
			}
		});
	});

}

AddPage.html

<script>
 	$.getScript(path + "js/AddPage.js");
</script>
<p>
	Currently <b>AddPage.html</b> page is loaded.
</p>

<input type="button" value="BACK" onclick="currentPage.back();" />

<div id="addUser">
	Name:<br>
	<input name="name" type="text" id="name"/><br>
	Office Number:<br>
	<input name="officeNumber" type="text" id="officeNumber"/><br>
	Phone Number:<br>
	<input name="phoneNumber" type="text" id="phoneNumber"/><br>
	Email:<br>
	<input name="email" type="text" id="email"/><br>
</div>

<div id="addButton">
	<input type="button" value="ADD USER" onclick="currentPage.add();">
</div>

DetailPage.html

<script>
 	$.getScript(path + "js/DetailPage.js");
</script>
<p>
	Currently <b>DetailPage.html</b> page is loaded.
</p>

<input type="button" value="BACK" onclick="currentPage.back();" />

<div id="addUser">
	Name:<br>
	<input name="name" type="text" id="name"/><br>
	Office Number:<br>
	<input name="officeNumber" type="text" id="officeNumber"/><br>
	Phone Number:<br>
	<input name="phoneNumber" type="text" id="phoneNumber"/><br>
	Email:<br>
	<input name="email" type="text" id="email"/><br>
</div>

<div id="editButton">
	<input type="button" value="EDIT USER" onclick="currentPage.edit();">
</div>

<div id="deleteButton">
	<input type="button" value="DELETE USER" onclick="currentPage.remove();">
</div>

ListPage.html

<script>
	$.getScript(path + "js/ListPage.js");
</script>
<p>
	Currently <b>ListPage.html</b> page is loaded.
</p>
<input type="button" value="Load Add.html" id="LoadAddButton" onclick="currentPage.loadPage('AddPage');" />
<ul id="itemsList"></ul>

Step 42

Repeat step 31 to preview your app.

You can find the source code here: https://github.com/datomnurdin/CRUD-worklight

Simple Ajax Data Retrieval (JSON)

Sometimes peoples keep asking me again and again how to do ajax data retrieval using JSON format. The technique is so simple.

http://stackoverflow.com/search?q=user:1922589+[json]

First thing, you need to setup your parameters (if needed) in formData variable. Then declare your URL, data type for response and request and callback (mostly success and error callback). Below is a sample for your ajax data retrieval. It request and response your JSON data. If you not really understand what is JSON, you can visit this website here.

http://www.json.org/

JSON

JSON

formData = {
    param1: param1
}
$.ajax({
    type: 'GET',
    contentType: 'application/json',
    url: "http://localhost/test.php",
    dataType: "json",
    data: formData,
    success: function(data) {
        console.log(data);
        //success handler
    },
    error: function(data) {
        //error handler
    }
});

Make sure your url can request and response JSON data. If you don’t know what it is, you can visit these websites for your clarification about this technique.

It’s easy right? Happy coding!!