Appcelerator's Titanium Studio (Titanium) is an interesting mobile development environment. Writing code in it isn't like anything else I've coded in it. This isn't necessarily bad, but it does take some getting used to. This post will be a multi-part review and tutorial. My goal is to learn the system by writing a calculator app. I am working with version 3.0 of Titanium. If you have read any of my previous posts, you may know that I have written a calculator app in jQuery Mobile for mobile websites and then easily ported it to PhoneGap for both iOS and Android. The question is how hard is it to build the calculator in Titanium.
This isn't a getting started tutorial. Titanium already has excellent tutorials to do that on their site. Instead, it is an exploration. If you need a tutorial check out the ones on Titanium's site at: Quick Start.
What is Titanium?
In order to build iOS code, you will need an Intel Mac, the same basic requirement that traditional iOS programming requires. Both PhoneGap and Icenium now make it possible to bypass the Mac requirement, but Titanium does not. But this isn't all bad. Just like traditional iOS, you can pick your deployment target. It can be a provisioned iPhone or iPad or their simulator.
Titanium is something different. First off, there is no DOM. That's right the worst API ever designed, the Document Model Object, doesn't exist in Titanium. While that should be good news, it does create a problem. How do you create UI? Unfortunately it is via code, which quite frankly sucks. I've been coding a long time, I remember the early days of UI programming, how fun it was to code out each and every UI element. Then I remember what is was like when NextStep arrived. It had the Interface Builder, it wrote the UI code for you, brillant. And while HTML/CSS isn't the ideal UI creation combo, it is leaps and bounds above building UI in code. Plus, it has the additional advantage of being well documented.
Now, in all fairness, I can see references in the documentation and website to something called, Alloy. And it appears that Alloy builds UI with XML, like Android or Windows Phone. I will check it out in a later post. But if Appcelerator really wants to make Titanium world class, it has to make a UI builder for it.
One of the worst parts of PhoneGap is debugging. No matter how good your code is, eventually you will need to debug it and nothing beats being able to set good old fashion breakpoints. PhoneGap doesn't really have a debugger. Wait - before people flood the comments - I know that there are ways to do debugging in PhoneGap. But none of them are optimal, none. Being able to stop the code at any arbitrary point and examine the environment - is a great help and a necessary part of development.
With Titanium you have it. I can set a breakpoint and run the code on either an Android or iOS device, emulator, or simulator. Being able to set a breakpoint is a real boon and helped me several issues already, especially since I refused to RTFM.
I began building the application by selecting the Single Window Application template. This template creates several versions of ApplicationWindow.js. Titanium doesn't try to create one code base for all systems. Instead it gives the developer a way to share a great deal of code between environments, but not all of the code. Each version of ApplicationWindow is tailored for a different platform. It also creates a view, FirstView. Think of windows as HTML pages and views as divs.
I renamed FirstView to KeyPad. All of the View code, this time view as MVC, goes in it. Titanium's support of CommonJS Modules makes it very easy to implement separation of concerns. The is no global space like traditional DOM programming. All of the communication between modules has to be planned.
My plan for the calculator is that KeyPad will be the view. App the controller. And a still unwritten module named Logic will be the model. Communication between the different modules will be mainly via events. And here is where I finally needed to RTFM.
In DOM programming to do communication between modules I would normally fire a custom event off of the Document, but there is no document in Titanium. I didn't want to do it off of the KeyPad, since the model should have no knowledge of the KeyPad. Finally, I found that you can fire events off via Ti.UI.fireEvents/addEventListener. I coded this up and tried it out. It worked under iOS, but not Android. I read the documents over and over but there wasn't any information about why this doesn't work under Android. Finally I googled it. Seems I'm not the only one who has encountered this issue. The solution is to use Ti.App.fireEvent/addEventListener instead. No explanation given as to why. This is part of the reason why I don't like to google things, I want to why not just how.
So far I have the code working in the KeyPad firing events. And some temporary code in app.js receiving them. Most of the time spent so far has been in hand coding the UI. It sucks but at least things work better than in DOM programming. I decided to use percentages for the buttons. In DOM programming width percents work correctly but height only works if you hard code the height of the parent container. In Titanium height percents work is exactly as you would think they should intuitively. This makes it a lot easier to code UI to be flexible based on its environment.
So far I like Titanium. It was a lot easier to get the environment up and running than PhoneGap. Plus I like being able to build for Android or iPhone in the same environment. I haven't finished the calculator yet, but I will. The complete source code is on GitHub at: Titanium Calculator. Please check it out. I will finish it sometime in January 2013 and let everyone in a future post.
Here is the link to second part of this post: Titanium Second Look.
Here is the KeyPad as it exist now: