Titanium: the Good, the Bad and the Ugly

I’ve been following Appcelerator Titanium Mobile with a keen interest since they decided, for mobile, to move from HTML to native UIs. I just love this idea: use the platform’s native UI controls from Javascript. I did have a fairly good experience doing a little test app with Titanium Mobile 1.5 and noted for myself to use it for real when I’ll have a project.

More recently Appcelerator bought Aptana, the arguably most advanced Eclipse plugin for Javascript (and HTML) development, and renamed it TitaniumStudio. Honestly I dislike Eclipse very much but I thought it was a great move to gain the professional developers’ hearts.

Since I had a new occasion to do a mobile app I thought I was time to get up to date by giving Titanium 1.8 another run.

This was a “mixed” experience, but my conclusion is quite positive!

Warning: MacOS stuff ahead ;)

The Good

Titanium API is pretty fantastic nowadays if you want to avoid the burden of getting into both the huge UI Kit framework and this Objective-C weirdo. You can code truly native UIs in a few lines of Javascript, and, hopefully, you’ll have a good base to create an Android version as well with a reasonable amount of modifications.

The Bad Studio

“Argh, please kill me now” – that’s me after a few hours using the “Studio”.

But I’ll first list the things that can be liked:

  • interactive Javascript debugger,
  • decent Javascript code completion and syntax checking.

That’s about it.

Now onto the painful things:

  • it’s Eclipse in all it’s glory: snappy as a dead horse, I’m dying a little each time I see the infamous “Building Workspace”,
  • I still didn’t understand the link between Eclipse’s regular top Debug/Run buttons and Titanium’s custom Debug/Run/Package buttons in the Project panel,
  • Javascript code completion isn’t quite as good as some other editors,
  • by default iOS apps are packaged for device into an IPA that you must then install manually through iTunes (and it’s awfully long to compile).

The balance isn’t in TitaniumStudio’s favor and I quickly decided to get back to the command line.

Getting rid of the Studio

Thankfully, the command line SDK still exists, and it generally works as expected!

If you installed TitaniumStudio, you’ll find it in:

/Library/Application\ Support/Titanium/mobilesdk/osx/1.8.0.1/

The SDK alone can be found in the Continuous Integration (CI) area, but beware, it’s a development area so if the ‘master’ is version 1.9 I suppose it’s safe to get the latest 1.8 build. Follow the dev blog to see what is the latest stable release.

In both cases you’ll run it from the command line like:

/<titaniumsdk>/titanium.py <args>

Now to create a new project:

/<titaniumsdk>/titanium.py create --type=project
--platform=iphone,android --name=MyProject --id=com.foo.myproject

and to run it in the iPhone simulator:

cd MyProject
/<titaniumsdk>/titanium.py run --platform=iphone

The basics are very easy, simple and fast (unlike in Eclipse) – now pick up your preferred Javascript editor and… where’s the code completion?

Where’s the Javascript API?

Well Appcelerator doesn’t provide any ready to use way to have code completion in other editors, but some cool people have worked on it:

Now any good JS editor will provide your with some code completion for the API – open the API documentation in your browser and get started. Also Google is your friend if you need samples. Easy.

Debugging

Now we’re out of the Studio we don’t have the nifty interactive debugger, but it’s ok:

  • we do have detailed errors reported (in the terminal with the iPhone simulator and in adb with Android),
  • and you’ll learn back to log and dump objects using Ti.API.log() or good ol’ alert()

Getting on the device

Apple has made it insanely difficult to target iOS without using XCode – and this time again we’re not going to fight.

iOS provisioning

  • if you don’t know what this is, you can stop reading now and consider paying the Apple tax to be allowed to dev for iOS and to get up to speed with creating provisioning profiles,
  • if you didn’t already create an iOS provisioning profile, create one,
  • if your provisioning profile doesn’t match the one you provided when creating the project, change it in ‘tiapp.xml’. Then clean your build (see ‘Troubleshooting’ below) and run the project once in the simulator,
  • if an installed provisioning profile matches the project XCode will detect it automatically.

Running from XCode

Titanium actually generates a usable regular XCode project in the build/ directory:

open build/iphone/MyProject.xcodeproj/

At first, for me, XCode doesn’t offer to run the app on my device (iPod Touch 4); here’s the solution to select your device:

  • select ‘Edit Scheme…’ in the toolbar’s Scheme combo box,
  • select the Scheme your interested in (like ‘MyProject-universal’),
  • then you can choose your device in the ‘Destination’ list.

Now clean the project (Command+Shift+K), wait until this completes, then press Run (Command+R), and the app should eventually start on your device – woohoo :)

The Ugly

Ok the experience of running the project in the iPhone simulator and even on an iOS device is pretty good, and iOS is clearly a first class citizen in Titanium API.

Now what about Android? Well don’t expect miracles and your app is going to look like shit (if it works at all) on Android. There will be work to do.

Also on my computer the interactive debugger (in the Studio) wouldn’t connect to the emulator, and from the command line I couldn’t make the “fastdev” server work (very good idea, similar as Spaceport.io’s excellent workflow). In this conditions targeting Android is just incredibly painfully slow but I have hopes that it’s only a problem with my config.

I’m confident it can be solved however, and I suppose I’ll find a way (probably thanks to “fastdev”) to directly run on an Android device because the emulator workflow is ridiculously slow for now.

Troubleshooting

Because there will be troubles.

Cleaning a project

Sometimes changes/assets are not picked up in the simulator:

# Warning: "rm -rf" is a very dangerous command
rm -rf build/iphone/
rm -rf build/android/

Note: strangely you may have to build twice (yeah) after a cleanup.

Code completion conflict

When building, many copies of your JS files will be created under build/ and some editors may be confused by older versions of your code – I personally automatically delete all the JS copies after a simulation:

# Warning: "rm -rf" is a very dangerous command
find build/iphone/ –name "*.js" rm -f {} \;

Note: this trick doesn’t work well with Android target, you have to clean the Android build completely instead.

Automating

You don’t want to mess with all these commands in the terminal (especially those with “rm -rf” inside) so you should write scripts!

Here’s my ‘titanium.sh’ script:

#!/bin/bash
/Library/Application\ Support/Titanium/(...)
(...)mobilesdk/osk/1.8.0.1/titanium.py $@
if [[ $1 == run ]]
then
find build/iphone/ –name "*.js" -exec rm -f {} \;
fi 

Make it executable:

chmod 755 titanium.sh

I’m keeping those in /usr/local/bin (note that you must use sudo to edit them) so they are in the path and I can type in the terminal:

titanium.sh run --platform=iphone

Sublime Text 2

My preferred text editor on Mac has some useful plugins for JS dev. Using Package Control you can install:

  • SublimeCodeIntel: code completion (I usually disable its CSS completion),
  • SublimeLinter: syntax checking (my JS syntax preferences),
  • Terminal: open the terminal in current file’s location

A super trick, to run my project from ST2 without even opening the terminal:

  1. Tools > Build System > New Build System…
  2. paste this build config (and check the reference),
  3. save as ‘Titanium.sublime-build’ in the default location (ie. in ST2/Packages/User/),
  4. restart ST2,
  5. now you can select this build system in Tools > Build System menu and press Command+B to run the project and enjoy the log directly in ST2 console.

Notes:

  • it works better to exit (Command+Q) the simulator as soon as you don’t use it, and always before launching a new build,
  • SublimeCodeIntel doesn’t support CommonJS modules so stick to Ti.include() and regular prototype-based Javascript.

Final notes

Now that everything is properly setup I’m having a lot of fun using Appcelerator Titanium; so far it has been working pretty fantastically: the API is quite intuitive and you can find plenty of sample code, and tricky things, like loading data/images from the web, just work without any effort. And if the API isn’t good enough, I know I can dig into the Objective-C/Java side to extend/fix it.

Warning: it’s not because it’s Javascript that everything is easy to do, you must be very careful about your memory consumption and code quality. Also avoid running several Javascript contexts (ie. calling createWindow with an ‘url’ property); check the Tweetanium project for some good practices.

Next thing to try: using haxe-js and the Titanium API externs to develop the app.

  1. Fernando says:

    Great post! I had to use Titanium and OSX a few months ago and faced some problems just like those you pointed out.

    Your scripts and tips will help me a lot. Thanks! :D

  2. bananos says:

    Thanks for great review, I tried Titanium one year ago and it was a painful experience, but recently I played around with the new 1.8 SDK & Titanium Studio and must say that it matured a lot — especially iOS support & documentation was greatly improved.

    As for iOS provisioning I’ve even posted some notes on this topic — as you’ve mentioned it’s not that easy:

    http://webapp.org.ua/dev/preparing-adhoc-distribution-in-titanium-mobile/

  1. There are no trackbacks for this post yet.

Leave a Reply