Wednesday, 20 June 2012

A Rhodes Journey - Getting started with RhoStudio on OSX Lion

is a cross-platform open source mobile development framework that is  by . in some aspects of development. Rhodes was developed by RhoMobile, which was recently acquired by 

We started checking out Rhodes a year ago when using Snow Leopard as a development platform, and developed some trial apps. At that time, Rhodes used to be a simple gem that could be downloaded using the compatible Ruby (v 1.8.7) and rvm. Since I recently upgraded to Lion, I thought I'd give Rhodes another spin to see if it had changed. Indeed, I found that RhoMobile has grown by leaps and bounds, and that Rhodes is now a small part of a much larger scheme of things: Rhodes now ships within  which includes, apart from Rhodes, an IDE called  for developing RhoMobile applications, and two other frameworks called  and .

In this post I'll explain how I went about setting up Rhodes 3.3.3 from the RhoMobile suite and running the sample APIs app for Rhodes (included with the  RhoStudio installer) on iOS and Android simulators using the RhoStudio IDE.

Installing the Prerequisites


First off, since I wanted to start developing for iOS, I needed to download and install the from the .

Next, to run iOS aps on OS X I had to install the relevant simulators. These were not bundled with the XCode and had to be downloaded within XCode by going to XCode > Preferences > Downloads.

Here, we select the relevant iOS device simulators and XCode command line tools, which is a prerequisite of installing on OS X.

Note: if you don't want to develop for iOS and still want to install RVM (without installing XCode, as it is a heavy download), then you might need to install the to proceed.

Android SDK

In order to develop for Android, we need the and . These need to be downloaded and unzipped at a convenient location, which will be needed later to configure Rhodes and RhoStudio.

RVM and Ruby

Next, ensure that you have RVM and Ruby version 1.9.3 installed on your Mac. There is a step by step guide available . In my case I used RailsInstaller for installing Ruby on Rails, which also installed RVM. If you prefer GUIs then you may want to use  for managing RVM, rubies, gemsets and gems on your Mac.

Java Development Kit (JDK)

Rhodes also requires a JDK. For Lion, we need to install .

Installing RhoMobile Suite, RhoStudio and Rhodes

Now we are ready to download the Rhomobile suite installer dmg file from . Once downloaded, mount the dmg. 

Here, you can choose to proceed with installing the the entire suite provided by running the 'install gems on rvm' script file. However, I wanted to install only Rhodes, and thus, installed only the relevant gems using the following commands in Terminal:

gem install rhomobile-debug
gem install "/Volumes/Motorola RhoMobile Suite Installer/.gems/rhodes-3.3.3.gem"
gem install rhodes-translator

Next, copy the "Motorola" from the dmg into the Applications folder of your Mac and launch it from Applications. Upon launching, RhoStudio requests a workspace path that can be specified to a location of choice. Note that the Rhodes installation guide suggests that one shouldn't add a path with spaces as it causes problems with RhoConnect applications.

We need to configure the android SDK path in RhoStudio for it to build for android. Go to  RhoStudio > Preferences > RhoMobile > Android and add the paths for both SDK and NDK in relevant spaces. Click OK.

Building and Running the sample APIs application

Great, almost done now! 

Within the Rhomobile suite installer downloaded earlier, go to samples and copy the rhodes-system-api-folder to your workspace folder specified earlier. In RhoStudio, import the project by selecting File > Import > Existing Project into workspace. Choose the root folder as the workspace directory to see the project in the list. Select the project and click Finish. The project should now be listed in the Project Explorer.

Using the Android simulator

Before you can run the project on Android, you need to install the relevant SDK and Google APIs. To do so go to <android-sdk-macosx>/tools and run the file called 'android'. This should launch the Android SDK manager. Here we need to select the android versions that we want to build for. At the time of writing this post, the build.yml file is configured for android 3.0, which is what we will select in the SDK manager and install. 

After the installing the SDK platform, we also need to install the 'Google APIs' displayed under the installed SDK in the SDK manager. This is used by some Rhodes libraries in the kitchensink project. 

In order to run the project, go to Run > Run Configurations...  and create a new configuration by double clicking RhoMobile Application. Select the platform as Android and Simulator type as Simulator. Make sure that Project name says rhodes-system-api-samples. Click Run to give it a go.

Note: If it fails with a message requesting you to run 'set-rhodes-sdk' then do so in the project directory in the terminal and try running again. The application takes between 2 to 5 minutes to launch on an android simulator. 

Using the iPhone simulator

To run for iPhone create another run configuration and this time choose the Platform as iPhone. Click on run to start building for iPhone. Once built, the studio will launch the iPhone simulator with the application loaded.  

All Done!

This concludes a walkthrough of how to set up Rhodes and RhoStudio on Mac OS X Lion.

We can now proceed to creating Rhodes apps for both Android and iOS platform with (hopefully) less effort than writing apps in separate native environments. 

Thursday, 7 June 2012

A Scope Gotcha In CoffeeScript

I think a , and — after developing with it throughout May — have grown to like it a lot. However, hidden amongst all the smooth elegance are a few rough edges, to confuse and cut the unwary. Like me. This is the story of a small scope that caught me out twice.

Thanks to , I might implement a widget to manage a list of items a little like this, and when the user clicks the fat arrow sets a allowing an easy call to my new object.

class Foo 
 constructor: ->
   @items = []
 doSomething: ->
 buildList: ->
   $ul = $('<ul/>')
   for item, index in @items 
      $li = $('<li/>')
      $li.on 'click', =>
        $li.addClass 'active'
      $ul.append $li

Except this doesn't quite work. To see why the active class ends up on last list element, take a look at the compiled :

var Foo;
var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Foo = (function() {
  function Foo() {
    this.items = [];
  Foo.prototype.doSomething = function() {};
  Foo.prototype.buildList = function() {
    var $li, $ul, index, item, _len, _ref, _results;
    $ul = $('<ul/>');
    _ref = this.items;
    _results = [];
    for (index = 0, _len = _ref.length; index < _len; index++) {
      item = _ref[index];
      $li = $('<li/>');
      $li.on('click', __bind(function() {
        return false;
      }, this));
    return _results;
  return Foo;

Oops - $li is defined right at the top of buildList. The context will contain the current value, from the last iteration.

There are several ways to improve this code and make this problem go away. One easy technique is just to factor out a method to build the list item.

class Foo 
 constructor: ->
   @items = []
 doSomething: ->
 buildListItem: (item, index) ->
      $li = $('<li/>')
      $li.on 'click', =>
        $li.addClass 'active'
      $ul.append $li
 buildList: ->
   $ul = $('<ul/>')
   for item, index in @items 
      $ul.append @buildListItem item, index

Though this applies equally to JavaScript, I think that the very cleanness of CoffeeScript allows this sort of bug to creep in more easily. The lesson to take away — keep CoffeeScript methods small and objects well factored.