Wednesday, September 01, 2010

Gotchas to getting started in Titanium

After promising myself to blog more, I ended up with my head down programming. But I'm back to let you know what I learned! About a week or two back, I got started using Appcelerator's Titanium. It's basically a framework that lets you to write native mobile apps in javascript that you can compile across multiple mobile platforms.

Titanium is actually set up like Shoes. Most of the application code is written in javascript, and then some of this code delegates its execution to Objective-C, like how in Shoes, it's Ruby up top, and for slow parts, the execution is proxy-ed to C. Therefore Titanium doesn't really "compile" to native Objective-C code, but rather, it's written in native Objective-C and uses the already built-in javascript to tie things together at the top application layer. On android, just replace Objective-C above with "Java".

I think it's a much better idea to have a scripting language on top of native code to tie things together at the application layer. Developer time goes much faster, and you definitely make less mistakes with memory management. However, there's a bunch of gotchas in getting started with Titanium. And while their marketing copy makes it seem like it's pretty painless, there's actually enough potholes in the way to stop you from even getting started.

To start, you need the correct combination of the iPhone SDK and the Titanium SDK in order to get it started and working. So make sure you have the latest SDK. I'm on the iPhone 4.0 SDK and Titanium Developer 1.2.1 with Titanium SDK 1.4.0. For those of you wondering, you can compile with a iPhone 4.0 baseline, but still compile to a lower iOS. I have a 2G iPhone running 3.1.3 firmware, and it runs fine since I'm not using any new APIs.

The other gotchas have to do with the javascript API. For example, when creating a button, we do something like this:

var logoutButton = Ti.UI.createButton({ title: "Logout", top: 55, left: 10, right: 10, height: 35 }); settingsWin.add(logoutButton);

Seems pretty easy, except the documentation doesn't mention that while you can have left and right co-exist to set left and right margins, you can't actually have both top and bottom co-exist to set top and bottom margins. If you do, it simply won't display your button, and you have no idea why.

Alternatively, there is no mention of what are required options and what are optional options. For example, for textfields:

var blurbField = Ti.UI.createTextField({ hintText: "Enter Note", height:35, top: 65, left: 10, right: 10, borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED }); contactWin.add(blurbField);

It seems pretty elementary, but it's required that you specify the borderStyle, or else your button and textfield will simply not be displayed with no error. Buttons and textfields also require a height, otherwise, the chosen default is the full size of the screen! That doesn't make any sense. Also, when using tableViewRows, all rows with a different layout need to have a different className, for the native app to be able to conserve memory.

None of these gotchas are intuitive, and confuses the heck out of people, but I realize they're obvious to those that have first worked in Objective-C and then in Titanium. Given the goal of Titanium is to provide web devs an "in" to writing native apps without writing in native code, I'd say it's not there yet. Titanium is at best a leaky abstraction on top of the native code.

The worst part about using Titanium is its include mechanism. It isn't at all like include or require in other languages. It's actually more basic then that--essentially just a cut and paste of code. After I realized it's not a mature javascript development environment that you might be use to with in-browser javascript or node.js, things went a lot smoother. In a later post, I'll talk about Ti.include() and the follies that come with it, so you save yourself some headaches down the road.

Posted via email from The Web and all that Jazz


  1. Anonymous9:57 AM

    Fully agree, getting it to install is a pain. Haven't got it to recognize either iOS or Android SDK.

  2. Titanium SDK was able to recognize the older XCode SDK if I lowered the Titanium SDK version to 1.2.0

    But to make it work with Titanium SDK 1.4.0 Make sure you have the latest version of the Xcode SDK (4.0 I think).

  3. Titanium can be a huge pain, but it's not so bad if you know what to avoid (though the docs don't help too much either).

    It now has a basic implementation of CommonJS's require(), which is what I'm using in my project (while staying the hell away from Ti.include()).