Instant backend for your Phonegap app

Using Phonegap to create apps with HTML, CSS or JavaScript? Add an instant backend to your project with the Kii Javascript SDK. Since PhoneGap logic is normally coded in Javascript and the framework allows you to incorporate plugins and libraries, it’s an easy way to extend your mobile architecture with reliable performance and elastic scalability in the cloud. Below you’ll find a simple tutorial that walks you through the process.

Custom Employee Directory Demo

This tutorial is based on this excellent demo (source code) for a simple employee directory created by Christophe Coenraets. We drop in the Kii Javascript SDK and a Kii data adapter (learn more about data adapters here), which allows you to store the data in the cloud. We’ll learn how to use different data storage strategies in this demo.

With the original project, you can switch between:

  • In-Memory Adapter
  • LocalStorage Adapter
  • WebSQL Adapter
  • JSONP Adapter

Each adapter provides an API suitable for initialization and finding employees by name and ID. We’ll code a new Kii Adapter so all data storage in done on the cloud.

Initial Setup

To set up this demo:

  1. Install Phonegap.
  2. Create an app on developer.kii.com as described in our quick start guide.
  3. Choose Javascript as your platform and note your assigned app id and key. We’ll choose US for our server location here.
  4. Clone (or fork) the demo via Git and replace the app id and app key on kii-adapter.js. The Kii js SDK is already placed on the www/lib directory or you can grab it here to try it in a different project.

Now you’re ready to run the demo. For example, using an Android phone via:

phonegap local run android

You’ll see some debugging messages related to Kii via logcat (open Eclipse with Android support and then the logcat view).

Inside the Demo

Once your demo is running, you’ll see a search box for finding employees by name (which uses FindByName described below). When you click on an employee, you should see his or her contact info (which uses FindById, also explained below).

employee_dir

Initialization

The data adapters provide 3 methods: initialize, findByName and findById. We piggyback on the initialization to init Kii with the proper app id and key:

// Initialize Kii
Kii.initializeWithSite("YOUR_APP_ID_HERE", "YOUR_APP_KEY_HERE", KiiSite.US);
console.log("Kii initialized");

Note that we use a fixed username and password for the sake of simplicity. You will want to adapt this demo to provide a welcome screen that allows the user to provide credentials for login/signup. The signup process is straightforward:

// Create the KiiUser object
var user = KiiUser.userWithUsername(username, password);
// Register the user, defining callbacks for when the process completes
user.register({
    // Called on successful registration
    success: function (theUser) {
        // Print some info to the log
        console.log("User registered!");
        console.log(theUser);
        // Store sample data on Kii backend (user level bucket)
        storeEmployees(theUser);
    },
    // Called on a failed registration
    failure: function (theUser, errorString) {
        // Print some info to the log
        console.log("Error registering: " + errorString);
    }
});

And the login process is even easier:

// Authenticate the user
KiiUser.authenticate(username, password, {
	// Called on successful registration
	success: function(theUser) {
	   // Print some info to the log
	   console.log("User authenticated!");
	   console.log(theUser);
	   // Store sample data on Kii backend
	   storeEmployees(theUser);
	},
	// Called on a failed authentication
	failure: function(theUser, errorString) {
	   // Print some info to the log
	   console.log("Error authenticating: " + errorString);
	   // Try a signup, see above
        }
})

We also create the set of employees on the cloud if they are not present on the backend:

function saveObjects(bucket) {
    var deferred = $.Deferred();
    // Iterate over employee list
    for (var i in employees) {
        var employee = bucket.createObject();
	// Iterate over employee attributes
	for(var attr in employees[i]){
	    employee.set(attr, employees[i][attr]);
	}
	// Save the employee
	employee.save({
		success: function(theObject) {
		    console.log("Employee saved!");
		    console.log(theObject);
		},
		failure: function(theObject, errorString) {
		    console.log("Error saving employee");
		}
	});
    }
    deferred.resolve();
    return deferred.promise();
}

FindByName

This method runs a query that matches entered text to the beginning of a first or last name, displaying up to 10 matching results:

// Create a user scope bucket named "employees"
var user = KiiUser.getCurrentUser();
var bucket = user.bucketWithName("employees");
// Create the conditions for the query
var clause1 = KiiClause.startsWith("firstName", capitaliseFirstLetter(searchKey));
var clause2 = KiiClause.startsWith("lastName", capitaliseFirstLetter(searchKey));
// Merge the conditions together with an OR
var totalClause = KiiClause.or(clause1, clause2);
var query = KiiQuery.queryWithClause(totalClause);
query.setLimit(10);
query.sortByAsc("id");
// Define the callbacks
var queryCallbacks = {
   success: function(queryPerformed, resultSet, nextQuery) {
      console.log("findByName Query returned successfully. Result set size: " + resultSet.length);
      var results = [];
      for(var i=0; i < resultSet.length; i++) {
         var employee = new Object();
         // Iterate and set object attributes
         for(var attr in employees[i]){
	     employee[attr] = resultSet[i].get(attr);
         }
         // Save reconstructed object in result list
         results[i] = employee;
      }
      deferred.resolve(results);
   },
   failure: function(queryPerformed, anErrorString) {
      // do something with the error response
      console.log("Query returned with error: " + anErrorString);
      deferred.resolve(null);
   }
}
// Execute the query
console.log("Executing query");
bucket.executeQuery(query, queryCallbacks);

With Kii queries you can do clause nesting and filtering.

FindById

Here the query matches the employee ID entered as a parameter. No need to look at other contact info:

// Create a user scope bucket named "employees"
var user = KiiUser.getCurrentUser();
var bucket = user.bucketWithName("employees");
// Build the query
var query = KiiQuery.queryWithClause(KiiClause.equals("id", id));
query.setLimit(1);
// Define the callbacks
var queryCallbacks = {
   success: function(queryPerformed, resultSet, nextQuery) {
      console.log("findById Query returned successfully. Result set size: " + resultSet.length);
      if(resultSet.length > 0) {
         var employee = new Object();
         employee.id = resultSet[0].get("id");
         // Iterate over employee attributes
         for(var attr in employees[0]){
	    employee[attr] = resultSet[0].get(attr);
         }
         deferred.resolve(employee);
      } else
         deferred.resolve(null);
   },
   failure: function(queryPerformed, anErrorString) {
      // do something with the error response
      console.log("Query returned with error: " + anErrorString);
      deferred.resolve(null);
   }
}
// Execute the query
console.log("Executing query");
bucket.executeQuery(query, queryCallbacks);

This method retrieves all contact-specific information.

As you can see it’s quite easy to include Kii’s Javascript SDK in your Phonegap or Titanium project. Note that starting from Kii SDK version 2.1.12, jQuery is not a requirement (now optional) and the SDK is intelligent enough to switch XMLHttpClient automatically with the following priority:

  1. If jQuery is defined, SDK uses jQuery ajax.
  2. If XMLHttpRequest is defined, SDK uses XMLHttpRequest.
  3. If Titanium is defined (use KiiSDK in Titanium), SDK uses Titanium.Network.HTTPClient.

We love using the updated and original project by Christophe for this demo, dropping in the Kii Javascript SDK and Kii data adapter. If it’s more convenient, you can also find the project together with the adapter on GitHub.

Happy coding!

- Share -

German Viscuso

More posts from

  • Kii IoT platform enables customers to create smart, connected solutions and services
  • Long track record of supporting customers like Docomo, Toshiba, Kyocera and many others
  • Strong ecosystem partners across the globe, consisting of carriers, device/sensor manufacturers, system integrators, network/infrastructure providers, chip vendors and solution developers
  • HQ in Tokyo, US HQ in Silicon Valley & offices in China, Taiwan, Hong Kong and Europe (UK, Spain, Germany)
  • www.kii.com