Showing posts with label Appcelerator. Show all posts
Showing posts with label Appcelerator. Show all posts

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.

Appcelerator Titanium App using Hyperloop JS

Appcelerator Titanium App using Hyperloop JS

There are very simple steps to setup hyperloop in your system.

There are two way to setup hyperloop in your system.
1: User specific and local to user directory access.
2: Global and accessible to all user through environment variable.(will require admin access)
(Search for "Global and accessible to all user" to reach there.)

1: User specific:
1: Clone the hyperloop JS directory onto your system from link: https://github.com/ashishnigam/hyperloop
2: goto the cloned directory and go into the hyperloop bin directory.



3: use the hyperloop command and install any dependency which is missing and pointed by hyperloop.
Command Example:
./hyperloop compile --platform=ios --src="/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/helloworld/app.hjs" --dest="/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/helloworld /build"

4: It will ask you for number dependency like:
  • colors
  • underscore
  • uglify-js
  • node-appc
  • ejs
  • node-uuid
  • wrench
  • async
  • semver
  • byline
  • stream-buffers

5: you have to install them as well before you can run hyperloop compiler, which can be done using following command.

  1. sudo npm install colors
  2. sudo npm install underscore
  3. sudo npm install uglify-js
  4. sudo npm install node-appc
  5. sudo npm install ejs
  6. sudo npm install node-uuid
  7. sudo npm install wrench
  8. sudo npm install async
  9. sudo npm install semver
  10. sudo npm install byline
  11. sudo npm install stream-buffers

6: you can also make a piped call to execute one after another or write a script to make it automated.

7: Once installed then you can go to example directory to see the possible examples of hyperJS and test any for iOS or Windows environment.

Global and accessible to all user
1: Simple use the command in terminal and will install all the dependencies and setup hyperloop environment.
sudo npm install -g git://github.com/appcelerator/hyperloop.git

Then all set now you can use the below mentioned command.

Final Command to use for application build and testing:

hyperloop package --platform=ios --src=/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics --dest=/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics/build/physics --name=physics --appid=com.physics --launch --jsengine=jsc --clean --debug --hl-small 

It will create a build iOS project and launch the app in simulator.

In the Above command "/Users/ashish.nigam/GitHub/Appcelerator/hyperloop/examples/ios/physics" is the path of my hyperloop JS file.

You can find couple of example in the example directory with in cloned directory.


Sample app.hjs file code:

/**
 * simple example showing off the new iOS7 physics capabilities
 */
@import('Foundation');
@import('UIKit');
@class('DynamicBehaviorDelegate',NSObject,[],[
{
name: 'tapped',
returnType:'void',
arguments: [{name:'gesture',type:'UITapGestureRecognizer *'}],
action: tapped
}
]);
String.prototype.toUTF8 = function() {
return NSString.stringWithUTF8String('' + this);
};
var win = UIApplication.sharedApplication().keyWindow;
win.backgroundColor = UIColor.redColor();
var view = new UIView();
view.frame = win.frame;
win.addSubview(view);
var label = new UILabel();
label.textColor = UIColor.darkTextColor();
label.frame = CGRectMake(20, 20, 280, 50);
label.font = UIFont.systemFontOfSize(18);
label.textAlignment = NSTextAlignmentCenter;
label.text = 'Click to drop...'.toUTF8();
label.lineBreakMode = NSLineBreakByTruncatingTail;
label.numberOfLinesMode = 2;
view.addSubview(label);
var delegate = new DynamicBehaviorDelegate();
var gesture = UITapGestureRecognizer.alloc().initWithTarget(delegate,NSSelectorFromString('tapped:'));
view.addGestureRecognizer(gesture);
var animator = UIDynamicAnimator.alloc().initWithReferenceView(view);
var gravityBehavior = UIGravityBehavior.alloc().initWithItems(null);
var collisionBehavior = UICollisionBehavior.alloc().initWithItems(null);
collisionBehavior.translatesReferenceBoundsIntoBoundary = true;
var itemBehavior = UIDynamicItemBehavior.alloc().initWithItems(null);
itemBehavior.elasticity = 0.6;
itemBehavior.friction = 0.5;
itemBehavior.resistance = 0.5;
animator.addBehavior(gravityBehavior);
animator.addBehavior(collisionBehavior);
animator.addBehavior(itemBehavior);
function tapped(params) {
var num = Math.floor(Math.random()*10) % 10 + 1;
var filename = "m"+num;
var image = UIImage.imageNamed(filename);
var imageView = UIImageView.alloc().initWithImage(image);
view.addSubview(imageView);
var tappedPos = gesture.locationInView(params.gesture.view);
imageView.center = tappedPos;
gravityBehavior.addItem(imageView);
collisionBehavior.addItem(imageView);
itemBehavior.addItem(imageView);
if (label.alpha > 0) {
UIView.beginAnimations(null,null);
UIView.setAnimationDuration(2);
label.alpha = 0.0;
UIView.commitAnimations();
}
}


Hyperloop JS apps are much performance oriented than Titanium SDK App, but in current scenario you need to understand Native Language Concept to get benefits out of it.

Feel Free to ask any query related to Hyperloop JS and in case you find some bug then report in GitHub(https://github.com/appcelerator/hyperloop/issues).

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.