Appcelerator, getting better

After sticking to native for any mobile development for a while, and doing quite a bit of non mobile work lately, I semi recently found myself in the position to give Appcelerator another try. All of my previous experience with it had been from the perspective of bug fixing already started apps. This project marked my first chance to start an Appcelerator project with a clean slate and I was excited to give it a more fair chance. From the projects that I’ve encountered in the past it was apparent that out of the box Appcelerator makes it easy for less experienced and/or less anal developers to just lump all of their code all together into an interesting pile of long hard to read code with no clear separation of concerns and then proceed to fall into all of the standard traps of doing so.

Appcelerator-on-Rails

After a quick (likely mid foosball) conversation on the topic with my Productive Edge coworker Ed Lafoy, who has been doing a healthy bit of significantly nice looking Appcelerator work lately, he quickly pointed me to a blog post by the author of Appcelerator-on-rails and associated github project. This quickly proved to be a sufficient simple option for easily splitting things up a bit into more logical order with decent separation of concerns. Even this simple separation was enough to greatly improve the appcelerator development experience. My first concern was that the project in github had not been updated in nearly a year with several outstanding reported bugs with no posted solutions which had me concerned about getting hooked on a dead project. Fortunately after posting solutions to some of the open issues the original owner of the project was very quick to respond and merge in the fixes which eased my concerns. If using appcelerator I definitely suggest at least trying this out.

Edit: since initially writing this the guys at appcelerator have informed us that they recommend using commonJS modular design instead of MVC, I'm currently unconvinced that it is a better fit for this problem then something like Appcelerator on Rails but definitely better nothing or spending time rolling your own.

Style

The next thing that helped clean things up and avoid repetitive code that I highly recommend is to add in some sort of themeing layer. I've seen several people on forums using various forms of functions that return an object of a given style:


function buildGreenButton() {
return Ti.UI.createButton({/* dictionary definition for your green button */});
}

I went a slightly different direction, defining a dictionary of theme items in a separate file (Resources/themes/default.js in my case) with entries like:

themeDef['bodyWrapper'] = {
right:10,
left:10,
top:10,
bottom:12,
height:'auto',
borderRadius:10,
backgroundColor: 'transparent',
backgroundImage:'/images/body_background.png'
};

themeDef['title'] = {
textAlign: 'center',
height: 'auto',
width: '100%',
top: 9,
color: '#433f39',
font:{fontFamily:'Helvetica Neue',fontSize:18.5,fontWeight:'bold'}
};

themeDef['fieldButton'] = {
height: 50,
width: '100%',
backgroundImage: '/images/textfield_background.png',
top: 6,
borderRadius: 12,
borderColor: '#bbbbbb'
}

themeDef['fieldLabel'] = {
textAlign: 'left',
height: 'auto',
width: '100%',
top: 15,
left: 15,
color: '#8a8580',
font:{fontFamily:'Helvetica Neue',fontSize:18.5,fontWeight:'bold'}
};

Then defined a couple globally accessible functions:

function themeItem(themeStyle, localStyle) {
return arrayMerge(arrayMerge(themeDef['global'], themeDef[themeStyle]), localStyle);
}

function arrayMerge(left, right) {
var rv = {};
for (var key in left) {
rv[key] = left[key];
}
for (var key in right) {
rv[key] = right[key];
}
return rv;
}

This allows you to pass in a dictionary of values to add to or override theme defaults. Then after including the theme file, when ever I want to create a new field label it can be done in one nice clean line:

// Doesn't that look better then having everything in fieldLabel taking up space in your view code?
var label = Ti.UI.createLabel(themeItem('fieldLabel', {text: L('required')}));

Closing thoughts

Appcelerator has improved quite a bit over the past year and with a few little additions my opinion of Appcelerator has improved quite a bit. I think it's arguably the best option at the moment other then native and it is a good choice if you can't develop natively, but I still think you are better off going native if you can. Where I see it currently being most useful is for web developers with a strong basis of javascript wishing to get into mobile development without the time or ability to learn new programming languages that will be sticking to more or less the basics. Appcelerator is a cool solution to an interesting problem, but it still has room to mature and improve. I will definitely be keeping an eye on it but will happily continue to implement natively for now.

Tags: