Universal Apps in Appcelerator

Appcelerator is by far the best mobile rapid development platform out there, but they’re lacking a major feature – Universal app support.  Universal App support is the ability for an app to run in native resolutions on both the iPhone and iPad platforms.  Until now, you had to produce two versions of your app – an iPhone app and an “HD” app for your iPad.  This has its benefits – apps typically selling for $0.99 on an iPhone will often go for $2.99 or more for the “HD” version, but what if you want to write a Universal App?  With Appcelerator, you’re out of luck, until now.

With a simple hack, you can get your application to be a Universal App.  Coles notes: Change the “Targeted Device Family” to iPhone/iPad in your Xcode Active Target settings.

Using XCode to work with Appcelerator

This hack is predicated on my preferred way of using Appcelerator: (hint: it’s not using the Titanium IDE). The Titanium IDE and build process is a horrible way to work with Appcelerator. If that was my first introduction to Appcelerator, I would never continue with it. Creating a project is buggy, rebuilding it buggy. Sometimes it picks up your changes, sometimes it does a full build and makes you wait forever, sometimes you want it to do a full build and it doesn’t; the whole process is just a bad hack.  So when I use Appcelerator, I:

  • Create the project with Titanium.
  • Open the .Xcodeproj file that it created with Xcode.
  • Never open Titanium again

You can reload your app much quicker by simply using the Console view in Xcode.  Once you build and run it with XCode, you can simply hit the “Restart” button, and your code will be instantly reloaded, no recompilation, nothing. There are however, some caveats (see here).

Universal Apps

There are two possible reasons why you’d want to write a universal app with Appcelerator: to produce one, universal version of your app, or just to minimize the amount of code you have to write and maintain between your normal and HD versions of your app. As far as I can tell, Appcelerator encourages you to write either an iPhone or iPad app, even though it gives you two distinct targets in XCode (App and App-iPad).  But writing two distinct apps, as I have done in the past, is a waste – you end up reimplementing way too much of your business logic and duplicating it in two places.  It’s much better to follow the DRY (Don’t Repeat Yourself) principle.

Universal App architecture

MVC Directory Structure

MVC Directory Structure

Regardless of if you actually plan on delivering two distinct apps (normal and HD) or not, you’ll want to architect your application in such a way that you can maximize the sharing of code.  This means using Object-oriented Javascript and a true MVC (Model-View-Controller) paradigm in your code organization.

First we’ll start off with app organization. This seems simple, but it isn’t.

The first thing an Appcelerator app does when loading your app is to run “app.js”.  So our app.js looks something like this:

1
2
3
4
5
<code>var window = Ti.UI.createWindow(
{
url: "views/main.js"
});
window.open();</code>

What this does is open up a new window, with a new execution context in the views/main.js file.  This is great, because when we include further javascript files, they will all be loaded from the 2nd-level directory (i.e. views, controllers, include, etc.).  If we had stayed within the first execution context, we wouldn’t have been able to organize our files so nicely, since everything would have to be loaded from the base directory. You can read more on execution contexts here.

Object-oriented Architecture

In modern programming app design, we want to write and maintain as little code as possible, which means re-using code wherever possible.  In order to do this with Appcelerator, we need to use good inheritance and OO design principles.

First, we should create a base controller class. This uses a custom inheritance scheme by John Resig (code attached at the end of the article).

controllers/app_controller.js

1
2
3
4
5
6
Ti.include("../include/inheritance.js");
 
var AppController = Class.extend({
// application logic that is common to your application
  doLayout: function() {}
});

Then, extend these classes for iPad and iPhone specific logic:

controllers/iphone_controller.js

1
2
3
4
5
6
7
8
9
Ti.include("../controllers/app_controller.js");
var iPhoneController = AppController.extend({
    // application logic that is specific to iPhones
  doLayout: function()
  {
    // Layout code specific to iPads
    this._super.doLayout();
  }
});

controllers/ipad_controller.js

1
2
3
4
5
6
7
8
Ti.include("../controllers/app_controller.js");
var iPadController = AppController.extend({
// application logic that is specific to iPads
  doLayout: function() {
    // Layout code specific to iPads
    this._super.doLayout();
  }
});

Then, in your views/main.js file:

1
2
3
4
5
6
7
8
9
10
11
var ipad = Titanium.Platform.osname === "ipad";
if (ipad) {
  Ti.include("../controllers/ipad_controller.js");
  var controller = new iPadController(win);
}
else {
  Ti.include("../controllers/iphone_controller.js");
  controller = new iPhoneController(win);
}
controller.doLayout();  // Get your hardware-specific controller to lay out your UI
controller.doSomething();

Voila! Lots of code-sharing and a nicely organized Object-Oriented app!

You may have noticed we’re not separating the controller code from the view code…  I must admit that I haven’t much figured out how to separate the controller logic from the view logic, mostly since controller code will invariably affect the iPhone’s UI widgets and there isn’t a lot of separation in this paradigm (unlike Ruby on Rails or other MVC frameworks where there is a clear delineation between views and controllers).  I’m sure this will be the discussion of a future post when I wrap my head around better organization.


(Contains 1 attachments.)

What Startup Weekend means for a Developer

Image representing Startup Weekend as depicted...

Image via CrunchBase

As developers, we’re an inventive bunch.

All day long, we sit around and figure out innovative ways of solving the world’s problems, one line of code at a time. So, it’s only natural that we come up with new ideas that solve bigger problems than the latest bug we’re asked to fix. But who has time to really follow through on that awesome idea, or to write that really great piece of software that does it better than anything else out there? Most of us don’t.

Enter the solution: roughly twice a year, a fantastic event known as Startup Weekend emerges to give us the opportunity to innovate! This event is a great chance to get that nagging idea out and to do something with it.

Startup Weekend brings together innovative young entrepreneurs through events held all over the world for an action-packed weekend of brainstorming, hard-core coding and bug squashing – all for the thrill to build a new product in a mere 54 hours. As developers, we are the jet fuel that propels that nebulous idea to its greatness as a final wondrous creation, and it feels great to stand up at the end of three long sleepless days and nights and show to the world that we are the kings of code. But other than showing off your coding Kung-Fu to the world, why should developers come out to startup weekend?

Reason #1: It’s fun

As a guy who just loves to build stuff, take it from me: Startup Weekend is fun. What self-respecting coder wouldn’t love a weekend of free food and working with really smart people to get something out the door? And if that doesn’t do it for you, then the serious party afterward will be sure to float your boat! (Although be sure not to go too crazy on Saturday or the jet fuel in your coding machine might be molasses on Sunday, when it counts the most. I speak from experience.)

Reason #2: Job Opportunities

Representatives from lots of local startups and established companies will be around, and they’re always in the market for their next rock star coder. And even if you don’t meet a guy who’s looking to hire, it’s never a bad idea to show off your mad skills to everyone in the community, since you never know when you’ll be looking for a new gig. Besides, having a great reputation as a killer coder will certainly present opportunities in the future, even if you aren’t looking for something now.

Reason #3 : Social Network Building

Not Really.

Last Startup Weekend*

As mentioned above, knowing people In The Know is never a bad thing. People from varying disciplines, from the arts, to education, business, and IT, come out to Startup Weekend, so it’s a great place to make some new friends.

Reason #4: Learn a New Language

Who doesn’t want to learn the intricacies of Erlang while trying to build the next Facebook in 54 hours? In all seriousness, Erlang looks horrible. I was at a presentation from the Edmonton Ruby User Group a few weeks ago where they presented Erlang – it really looks horrible.

OK, really seriously, as a developer, we are constantly pressured to keep up with the latest trends. If you’re a C# guy, maybe you’re partnered with a guy who knows Ruby or Java – why not give it a go and see how you like it? Being able to add another language to your resume, on top of the ten you already know, can only help you in the future, right?

Reason #5: Learn a New Skill set

This one is huge. Maybe in your current role as a programmer at a large company, or as a student, you don’t get a lot of leadership or project management opportunities. Well, now’s your chance! The great thing about Startup Weekend is that it’s all about pitching in wherever you can – so if your team is seriously lacking in leadership or another role, step up and give it a chance! Who knows – Monday, you might realize that you really hate programming and would rather manage people instead!

All in all, Startup Weekend is one of my favorite events in the Startup Edmonton group of events. The opportunity to get a group of smart people in a room and build something useful as fast as possible is truly amazing. Even if you don’t produce something that works, it’s a lot of fun and the benefits are numerous.

See you there!

* Not Really from Last Startup Weekend.

MVC in Appcelerator

Regardless of if you actually plan on delivering two distinct apps (normal and HD) or not, you’ll want to architect your application in such a way that you can maximize the sharing of code.  This means using Object-oriented Javascript and a true MVC (Model-View-Controller) paradigm in your code organization.

First we’ll start off with app organization. This seems simple, but it isn’t.

The first thing an Appcelerator app does when loading your app is to run “app.js”.  So our app.js looks something like this:

1
2
3
4
5
var window = Ti.UI.createWindow(
{
  url: "views/main.js"
});
window.open();

What this does is open up a new window, with a new execution context in the views/main.js file.  This is great, because when we include further javascript files, they will all be loaded from the 2nd-level directory (i.e. views, controllers, include, etc.).  If we had stayed within the first execution context, we wouldn’t have been able to organize our files so nicely, since everything would have to be loaded from the base directory. You can read more on execution contexts here.

Object-oriented Architecture

In modern programming app design, we want to write and maintain as little code as possible, which means re-using code wherever possible.  In order to do this with Appcelerator, we need to use good inheritance and OO design principles.

First, we should create a base controller and view class. This uses a custom inheritance scheme by John Resig .

common/controller.js

1
2
3
4
5
6
7
8
9
Ti.include("../include/inheritance.js");
 
var Controller = Class.extend({
    init: function(win)
    {
        this.win = win;
        win.controllerClass = this;
    }
});


common/view.js

1
2
3
4
5
6
7
8
9
10
11
Ti.include("../include/inheritance.js");
 
var View = Class.extend({
    init: function(win, controller)
    {
        this.win = win;
        this.controller = controller;
 
        win.viewClass = this;
    }
});

Now, we can create our real controllers and views:

controllers/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Ti.include("../include/inheritance.js");
Ti.include("../include/db.js");
Ti.include("../common/controller.js");
Ti.include("../views/main.js");
 
var MainController = Controller.extend({
    init: function(win) {
        this._super(win);
 
        // Create the view for this controller
        this.view = new MainView(win, this);
    }
});
 
(function() {
    var win = Titanium.UI.currentWindow;
 
    // Create our controller for this window.
    new MainController(win);
})();

As you can see, now we’ve got a main controller, which also instantiates a view.   Now, the view can handle all layout code, and the controller can respond to those events, and affect the view appropriately.  This works especially well when designing Universal Apps, as we can Design two views, a iPhoneMainView, and iPadMainView, and instantiate the appropriate one.

Now for the view code:
controllers/main.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Ti.include("../include/inheritance.js");
Ti.include("../include/db.js");
Ti.include("../common/view.js");
 
var MainView = View.extend({
    init: function(win, controller) {
        this._super(win, controller);
 
        this.layout();
    },
 
    layout: function() {
       // Your layout code.  Ti.UI.createLabel({}), etc.;
    }
 
});

I’ve created a Github project called Appcelerator-On-Rails to show this code. I use this template in all my Appcelerator projects and add to it when necessary.

Happy iPhone coding!

Rails CMS plugins

I’m currently working on a project that requires a built-in CMS solution to enable quick SEO and content modification by site administrators.  This is not an uncommon problem – pretty much every website requires content management, and it amazes me that Rails doesn’t come with something pre-built (OK, there are those that argue that Rails is a CMS, but there sure seems to be a lot of work involved in getting it there).  On the other hand, I can see why Rails doesn’t include a CMS, as it’s meant as a web framework, not a website framework.

There are several great CMS systems for Rails out there (check out this overview) – but Comatose, Radiant and Refinery are the front-runners.  Your options for integrating a CMS system into Rails pretty much fall into 3 categories [1]:

  1. Two side-by-side applications. – Pair an off-the-shelf CMS with a custom built application. Copy/paste the visual elements, and loosely wire the two together with a subdomain or some kind of web proxy to share the URL structure
  2. Extend the CMS – Build a proprietary plugin or extension for the CMS to implement the application features.
  3. Soup-to-nuts custom application. Build a complete CMS as part of the project.
  4. Use a Rails plugin CMS.

For an in depth look at the problem posed by existing Rails CMS solutions, check out this article (and thanks Aaron for the quote above).  The first option is not a great solution, as there is a lot of re-work and duplication, not to mention the potential for screw-ups (oops! who forgot to update the price list??).  #2 is a terrible idea because you’re stuck to the CMS you begin with, and #3 is plain wasteful.  #4 is definitely the best option, as it’s completely modular and does not interfere with your code business logic.

Comatose and Refinery both fall into the 4th and best option – Rails plugins. After looking at Comatose, it seemed that it was a bit simplistic for my needs (and it hasn’t been updated since 2008).  Refinery was much better, but still lacking in some areas.  My issue with Refinery is that you still have to hand-code a theme for the site, which makes it very difficult to separate the design from the implementation (especially if you want a web designer to make any of the changes for you).  And adding any new features or layouts requires intervention on the side of the programmer, not the designer. But the plugin-based system definitely offered some advantages, namely that I could code my regular Rails controllers and views as I normally would.

And that left Radiant, the 800-pound gorilla in the Rails CMS world.  Radiant is definitely the most mature Rails CMS out there, and its lengthy feature-set shows: its layout mechanism is beautiful to use via radiant XML tags, and its extensions mechanism makes it easy to add custom functionality. To this end, it’s possible for a non-technical person to completely change the look of a site without touching a line of code.

However, it suffers from problem #2 outlined above – you have to extend Radiant, Radiant does not extend Rails.  This basically means that you need to code a custom extension to implement any of your business logic, which to me is highly unacceptable.

In the end, I chose to have my cake and eat it too – I hacked Radiant to make it behave like a plugin.  My recommendation for a Rails CMS?  If you’re in the market for a simple CMS with not a lot of custom application functionality, then Refinery is your best bet.

Enhanced by Zemanta

Hello world!

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!

WordPress Themes