Showing posts with label android.. Show all posts
Showing posts with label android.. Show all posts

Monday, June 2, 2014

REST API development with NodeJS and Mongo DB

Brief description about NodeJS:
Node.js is a platform built on Chrome's JavaScript runtime for easily building fast,
scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.


So lets start with our main topic, without discussing more about other things.
Developing Rest APIs with node is also having one or more node module available in the market like expressJS and restify.js. Lots of pros and cons are also available on net.

For me everything has its own pros & cons, so i am using Restify.js here. As i find it easy.
So install NodeJS & MongoDb in your operating system and register it globally then install the required module.
1: MongoDB.
2: RestifyJS.
3: MongoJS.

MongoDB can be downloaded from http://www.mongodb.org/ and after installing nodeJS which can downloaded from http://nodejs.org/, you can instal restify and mongojs easily.

Commands to install both one by one.
1: npm install restify
2:npm install mongojs

Now create a directory and go inside that directory, within that directory create a package.json file.
This package.json file will be used when you package your project for distribution.
To auto generate package.json type in terminal "npm init" (Windows user first register node and npm in environment variable to access it globally.)

Command and its uses:
"npm init"

My Demo App Details: $ npm init This utility will walk you through creating a package.json file. It only covers the most common items, and tries to guess sane defaults. See `npm help json` for definitive documentation on these fields and exactly what they do. Use `npm install --save` afterwards to install a package and save it as a dependency in the package.json file. Press ^C at any time to quit. name: (app) HelloRestAPI version: (0.0.0) 1.0.0 description: This is my first rest API project entry point: (index.js) app.js test command: node app.js git repository: https://github.com/ashishnigam/Team_Dev_Work/tree/master/Servers/nodeJS/myapp keywords: Rest,REST, REST APIs, API, APIs, Rest API, Node API, NPM. author: Ashish Nigam license: (BSD-2-Clause) Copyright (c) 2014, Ashish Nigam All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. About to write to /Users/ashish.nigam/Documents/NodeHTTP_Server/app/package.json: {   "name": "HelloRestAPI",   "version": "1.0.0",   "description": "This is my first rest API project",   "main": "app.js",   "scripts": {     "test": "node app.js"   },   "repository": {     "type": "git",     "url": "https://github.com/ashishnigam/Team_Dev_Work/tree/master/Servers/nodeJS/myapp"   },   "keywords": [     "Rest",     "REST",     "REST",     "APIs",     "API",     "APIs",     "Rest",     "API",     "Node",     "API",     "NPM."   ],   "author": "Ashish Nigam",   "license": "Copyright (c) 2014, Ashish Nigam All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." } Is this ok? (yes) yes

After this, your package.json is generated and you can check the content of package.json by opening in any text editor.

After that to install the dependencies and add it to package.json, execute the below mentioned command in the terminal (within same directory in terminal).


$ npm install restify --save
$ npm install mongojs --save

Similarly you can install any dependency and add it package.json. a dependency key will be added automatically once you use the above mentioned command.

My package.json file generated:

{
  "name": "HelloRestAPI",
  "version": "1.0.0",
  "description": "This is my first rest API project",
  "main": "app.js",
  "scripts": {
    "test": "node app.js"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/ashishnigam/Team_Dev_Work/tree/master/Servers/nodeJS/myapp"
  },
  "keywords": [
    "Rest",
    "REST",
    "REST",
    "APIs",
    "API",
    "APIs",
    "Rest",
    "API",
    "Node",
    "API",
    "NPM."
  ],
  "author": "Ashish Nigam",
  "license": "Copyright (c) 2014, Ashish Nigam All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.",
  "dependencies": {
    "mongojs": "~0.13.0",
    "restify": "~2.8.1"
  }
}
See the dependency section, which i made it bold to highlight.

Now create a app.js file in the same directory and open it in your favourite text editor.

Require both the dependency in your app.js at the top. copy paste to write it at the top of your app.js

var restify = require('restify'); 
var mongojs = require("mongojs"); 
The two lines show above load the restify and mongojs modules using the require function and assign them to variables.
Now create a new server using restify API:
var ip_addr = '127.0.0.1';
var port    =  '8080';
 
var server = restify.createServer({
    name : "myapp"
});
 
server.listen(port ,ip_addr, function(){
    console.log('%s listening at %s ', server.name , server.url);
});
The code shown above creates a new server. The createServer() function takes an options object. We passed myapp as the name of the server in options object. You can view the full list of options in the documentation. After create the server instance, we call the listen function passing port, ip address, and a callback function.

Run the application by typing the following command.

$ node app.js
You will see following on the command line terminal.
myapp listening at http://127.0.0.1:8080

Configure Plugins

The restify module has a lot of built in plugins which we can use. Copy and paste the following in app.js. These should be added before the server.listen() function. Refer to documentation to learn about all the supported plugins.
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.CORS());

The three lines shown above :
  1. The restify.queryParser() plugin is used to parse the HTTP query string (i.e., /jobs?skills=java,mysql). The parsed content will always be available in req.query.
  2. The restify.bodyParser() takes care of turning your request data into a JavaScript object on the server automatically.
  3. The restify.CORS() configures CORS support in the application.

Configure MongoDB

Before adding the routes, let's add code to connect to myapp to the MongoDB database.
var connection_string = '127.0.0.1:27017/myapp';
var db = mongojs(connection_string, ['myapp']);
var jobs = db.collection("jobs");
In the code shown above, we connect to local MongoDB instance. Next, we get the jobs collection using database object.

Writing CRUD API

Now, we have the server and database part ready. We still need routes to define the behaviour of the API. Copy and paste the following code to app.js.
var PATH = '/jobs'
server.get({path : PATH , version : '0.0.1'} , findAllJobs);
server.get({path : PATH +'/:jobId' , version : '0.0.1'} , findJob);
server.post({path : PATH , version: '0.0.1'} ,postNewJob);
server.del({path : PATH +'/:jobId' , version: '0.0.1'} ,deleteJob);
The code shown above does the following:
  1. When a user makes a GET request to '/jobs', then findAllJobs callback will be invoked. The another interesting part is the use of versioned routes. A client can specify the version using Accept-Version header.
  2. When a user makes a GET request to '/jobs/123', then findJob callback will be invoked.
  3. When a user makes POST request to '/jobs', then postNewJob callback will be invoked.
  4. When a user makes DELETE request to '/jobs/123', then postNewJob callback will be invoked.
Now we will write the callbacks. Copy and paste the following to app.js.
function findAllJobs(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.find().limit(20).sort({postedOn : -1} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }else{
            return next(err);
        }
 
    });
 
}
 
function findJob(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.findOne({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }
        return next(err);
    })
}
 
function postNewJob(req , res , next){
    var job = {};
    job.title = req.params.title;
    job.description = req.params.description;
    job.location = req.params.location;
    job.postedOn = new Date();
 
    res.setHeader('Access-Control-Allow-Origin','*');
 
    jobs.save(job , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(201 , job);
            return next();
        }else{
            return next(err);
        }
    });
}
 
function deleteJob(req , res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.remove({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(204);
            return next();      
        } else{
            return next(err);
        }
    })
 
}
The code shown above is self explanatory. We are using mongojs API to perform CRUD operations.
We can test the web services using curl. To create a new job, type the command shown below.
$ curl -i -X POST -H "Content-Type: application/json" -d '{"title":"NodeJS Developer Required" , "description":"NodeJS Developer Required" , "location":"Sector 30, Gurgaon, India"}' http://127.0.0.1:8080/jobs
To find all the jobs
$ curl -is http://127.0.0.1:8080/jobs
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json
Content-Length: 187
Date: Sun, 24 Nov 2013 16:17:27 GMT
Connection: keep-alive
 
[{"title":"NodeJS Developer Required","description":"NodeJS Developer Required","location":"Sector 30, Gurgaon, India","postedOn":"2013-11-24T16:16:16.688Z","_id":"52922650aab6107320000001"}]
Complete app.js 
// Below shared app.js is prepared for uploading same project in open shift (RedHat directory).
// Will be sharing details of how to upload on open shift in my next blog.
#!/bin/env node
//  OpenShift sample Node application
var restify = require('restify');
var mongojs = require("mongojs");

var ip_addr = process.env.OPENSHIFT_NODEJS_IP   || '127.0.0.1';
var port    = process.env.OPENSHIFT_NODEJS_PORT || '8080';

var db_name = process.env.OPENSHIFT_APP_NAME || "localjobs";

var connection_string = '127.0.0.1:27017/' + db_name;
// if OPENSHIFT env variables are present, use the available connection info:
if(process.env.OPENSHIFT_MONGODB_DB_PASSWORD){
  connection_string = process.env.OPENSHIFT_MONGODB_DB_USERNAME + ":" +
  process.env.OPENSHIFT_MONGODB_DB_PASSWORD + "@" +
  process.env.OPENSHIFT_MONGODB_DB_HOST + ':' +
  process.env.OPENSHIFT_MONGODB_DB_PORT + '/' +
  process.env.OPENSHIFT_APP_NAME;
}

var db = mongojs(connection_string, [db_name]);
var jobs = db.collection("jobs");

var items = db.collection("items");

var server = restify.createServer({
    name : "localjobs"
});

server.pre(restify.pre.userAgentConnection());
server.use(restify.acceptParser(server.acceptable));
server.use(restify.queryParser());
server.use(restify.bodyParser());
server.use(restify.CORS());

function findAllJobs(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.find().limit(20).sort({postedOn : -1} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }else{
            return next(err);
        }
        
    });
    
}

function findJob(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.findOne({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }
        return next(err);
    })
}

function findItem(req, res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    items.findOne({_id:mongojs.ObjectId(req.params.itemId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(200 , success);
            return next();
        }
        return next(err);
    })
}

function postNewItem(req , res , next){
    var item = {};
    item.title = req.params.title;
    item.description = req.params.description;
    item.value = req.params.value;
    item.postedOn = new Date();

    res.setHeader('Access-Control-Allow-Origin','*');
    
    items.save(item , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(201 , item);
            return next();
        }else{
            return next(err);
        }
    });
}

function postNewJob(req , res , next){
    var job = {};
    job.title = req.params.title;
    job.description = req.params.description;
    job.location = req.params.location;
    job.postedOn = new Date();

    res.setHeader('Access-Control-Allow-Origin','*');
    
    jobs.save(job , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(201 , job);
            return next();
        }else{
            return next(err);
        }
    });
}

function deleteJob(req , res , next){
    res.setHeader('Access-Control-Allow-Origin','*');
    jobs.remove({_id:mongojs.ObjectId(req.params.jobId)} , function(err , success){
        console.log('Response success '+success);
        console.log('Response error '+err);
        if(success){
            res.send(204);
            return next();      
        } else{
            return next(err);
        }
    })
    
}

var PATH2 = '/items';

server.get({path : PATH2 +'/:itemId' , version : '0.0.1'} , findItem);
server.post({path : PATH2 , version: '0.0.1'} ,postNewItem);

var PATH = '/jobs';

server.get({path : PATH , version : '0.0.1'} , findAllJobs);
server.get({path : PATH +'/:jobId' , version : '0.0.1'} , findJob);
server.post({path : PATH , version: '0.0.1'} ,postNewJob);
server.del({path : PATH +'/:jobId' , version: '0.0.1'} ,deleteJob);


server.listen(port ,ip_addr, function(){
    console.log('%s listening at %s ', server.name , server.url);
});
Test the application with POST and get request.
Read steps below to start both DB and node server first.
Start MongoDB database server first, for this you have to go to your MongoDB bin directory and start(execute) mongod executable.
on MAC machine, command will work like this.
ashish-mac:bin ashish.nigam$ sudo ./mongod
// I used sudo to provide admin access, it depends upon your directory on which mongod resides.

Now you have to start the node server which we created just now, open another terminal window
and from there type in following command (move to project directory).

$ node app.js 
Now you are ready to make post and get request. so open another window and use below mentioned post request.
POST Request:
$ curl -i -X POST -H "Content-Type: application/json" -d '{"title":"NodeJS Developer Required" , "description":"NodeJS Developer Required ashish nigam" , "location":"Sector 30, Gurgaon, India"}' http://127.0.0.1:8080/jobs
GET Request: (Open your browser and use below mentioned IP and get request for all jobs)
http://127.0.0.1:8080/jobs
My Chrome browser image with get request:




Get a specific JOB POST:
http://127.0.0.1:8080/jobs/538c42d9a24b3e1b094e1aa6
Part which is common : http://127.0.0.1:8080/jobs while job id added after jobs.
538c42d9a24b3e1b094e1aa6        is JOB id in my sample request.
To find the get & post request path refer the following code section in app.js
var PATH2 = '/items';

server.get({path : PATH2 +'/:itemId' , version : '0.0.1'} , findItem);

server.post({path : PATH2 , version: '0.0.1'} ,postNewItem);



var PATH = '/jobs';

server.get({path : PATH , version : '0.0.1'} , findAllJobs);

server.get({path : PATH +'/:jobId' , version : '0.0.1'} , findJob);

server.post({path : PATH , version: '0.0.1'} ,postNewJob);

server.del({path : PATH +'/:jobId' , version: '0.0.1'} ,deleteJob);
Thank you for reading my BLOG.
Please share your feedback and any query regarding this blog are most welcome.

Reference Link:

Wednesday, May 28, 2014

Appcelerator Titanium Module for iOS Using Hyperloop JS

Appcelerator Titanium Module for iOS Using Hyperloop JS 

Hyperloop JS provided a unique solution for Module development and good part is these modules are compatible with current Titanium SDK. So module build using hyperjs will work as a native module.

To use Hyperloop code in a Ti.Current SDK such as 3.x.x, you should follow these steps below. NOTE: this will only work for iOS since other platforms use V8 which won't be supported in Ti.Next.
First, create a module.
Image
Inside the newly created module directory, create a directory named js. This is where we'll place our Hyperloop HJS files.
Let's do something simple. Create a file in the js directory named app.hjs with the following code:
Hyperloop module directory structure after build, we just need .zip file to use in Titanium App as Module.

 Hyperloop module directory structure, These are required directories and files.Rest can be deleted from the normal module directory structure.


@import("Foundation");
@import("UIKit");

/*
 Utility.
 */
String.prototype.toUTF8 = function() {
    return NSString.stringWithUTF8String('' + this);
};

/** 
 * because Ti.Next and Ti.Current have different threading architectures,
 * you can use the module.dispatch async to bridge the differences when doing
 * UI work or anything that requires you to use the main UI thread.  If you're 
 * using Titanium APIs, this isn't necessary since those APIs always work on the
 * right thread. However, if you want to use native APIs directly, you must wrap
 * your calls in the dispatch async.  This method is safe to use on both
 * Ti.Next and Ti.Current.  On Ti.Next, this simply executes the function as-is
 * when called since Ti.Next is already on the UI thread.  However, in Ti.Current,
 * this will execute the function on the main UI thread.
 */
module.dispatch_async(function(){
    var win = UIApplication.sharedApplication().keyWindow,
        label = new UILabel();
    label.textColor = UIColor.darkTextColor();
    label.frame = CGRectMake(20, 20, 280, 230);
    label.font = UIFont.systemFontOfSize(24);
    label.textAlignment = NSTextAlignmentCenter;
    label.lineBreakMode = NSLineBreakByWordWrapping;
    label.numberOfLines = 0;
    label.text = 'Hello world'.toUTF8();
    win.addSubview(label);
});

exports.foo = function(){
    return 'bar';
};
NOTE: Hyperloop compiled Ti.Current modules will use it's own Objective-C source code as part of packaging. Any code located in your Classes directory will not be used or compiled. You can safely ignore code in this file.
Now, compile your module using Hyperloop. For example, if my module was created in my directory located at ~/Documents/Appcelerator_Studio_Workspace/hyperloop_test_module, the command would be:
hyperloop package module --platform=ios --src=~/Documents/Appcelerator_Studio_Workspace/hyperloop_test_module --dest=build
After running the command, you should have your module zip distribution in the build directory.
Example Command i used on my system:
hyperloop package module --platform=ios --src=/Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/ --dest=/Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild
terminal output:
[INFO]  Compiling 822 source files
[INFO]  Generated universal library file at /Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild/libhjsmodule2.a
[INFO]  Compiling 6 source files
[INFO]  Creating module zip distribution
[INFO]  Created module distribution: /Users/ashish.nigam/Documents/Titanium_Studio_Workspace/hjsmodule2/hyperloopbuild/com.mhjs.module-iphone-1.0.zip
Deploy this file into your app using normal iOS module deployment instructions.
To load your Hyperloop code, just require the module as normal, substituting the module id for theYOUR_MODULE_ID string below.
var keyWindow = Ti.UI.createWindow({backgroundColor:"white"});
keyWindow.open();
var module = require("YOUR_MODULE_ID");
alert(module.foo());
Issues listed in: https://github.com/appcelerator/hyperloop/wiki/Using-Hyperloop-code-in-Ti.Current-SDK
feel free to ask any query related to module development, either Hyperloop JS module or Native Module.

Thursday, February 6, 2014

Appcelerator Titanium Module Development for Android

Module Development for Android 

(Using Titanium Version 3.2)



As Appcelerator has already documented well in the android module development part,
So here in this post i am going to write very practical approach which may help you guys for common module initialisation and linking issues.

There are two approaches for module development:

1: Using Terminal and the Eclipse for development and testing.
2: Using Titanium IDE for development, testing and deployment.

Both got their own benefit and drawbacks.

Here i am going to give Module development demo using eclipse, as except module creation in terminal all other things are same.

Terminal Command to create Module:

titanium320.py create --platform=android --type=module --name=<module name> --id=<module.id.reverseDomain> --android=<andorid sdk path>

Explanation:
titanium320.py :  is titanium.py (Titanium SDK version not CLI version) alias in terminal for mac and reference environment variable name in Windows.
name: module name which suits you.
id: module is as per need.
android: Android SDK path. 

Complete Sample command in my machine:
titanium320.py create --platform=android --type=module --name=calc --id=nigam.ashish.calc --android=/Applications/adt_bundle_mac/sdk

This will create a module in the directory you are currently in, in the terminal.

Module Directory structure will look something like this:

The Import the same in Eclipse where after import it should look something like this:


After that just check your build.properties file, it must contain all these properties for proper module build:

titanium.platform=/Users/ashish.nigam/Library/Application Support/Titanium/mobilesdk/osx/3.2.0.GA/android
android.platform=/Applications/adt_bundle_mac/sdk/platforms/android-10
google.apis=/Applications/adt_bundle_mac/sdk/add-ons/addon-google_apis-google-10
android.ndk=/Applications/android_ndk

Now all set, you are ready to build your first module.
Now right click on your build.xml file and go to "Run As" option and click on Ant Build first option.

Result: It will build the module and create module zip in the module source directory, which can be used in titanium application.

Testing on device or emulator:
Right click on your build.xml file and go to "Run As" option and click on Ant Build second option.
it will open a window where on little bit downside scroll, you see a screen like this:


Now you can choose to run on emulator or device:

This will be your screen after selection you can choose both as well but generally not required.

After that hit enter or click ok and it will build your module, create a zip in the module source directory and launch it on device or emulator.

How to use the build zip in Titanium App:

1: Launch Titanium.
2: Go to Help section.
3: Install titanium Module
4: Browse your module zip file path and choose project in which you want to install.
5: Click ok and done, you are ready to use the module in your app.js.

Note: Installing module in SDK Level is not required until module is very generic and will be used in most of the projects.

For Exposing More APIs in your module rather than just simple build, you can now open CalcModule.java file and start adding methods and properties.

Remember to expose methods and properties with proper annotation:

1: @Kroll.module(name="Calc", id="nigam.ashish.calc") //for module class
2: @Kroll.method
3: @Kroll.getProperty
4: @Kroll.setProperty
5: @Kroll.proxy(creatableInModule=CalcModule.class) //for any added proxy class.

There are many more but for exposing methods and properties only these are required.
You can check out lifecycle methods and events for proxy and viewProxy on Appcelerator GitHub Page.

Life cycle methods:

Methods Demo:

View proxy for exposing view:

View or creating custom view:

Passing Parameters to methods:

These are basics about view and proxy which can be seen from github.

Adding 3rd party JARs in module: 

Right Click on your project and click on build path--> configure build path --> and on libraries section add external JAR.

Browse the jar and add it to your project. Import the file in your class and start using them for module development.


Feel free to write your comment on this and any question related to android module development.