One of the biggest reasons to use Appcelerator Titanium is that, used correctly, it can produce native cross platforms apps, running on both Android and iOS, from a single codebase. Unfortunately, Titanium has often been misused and when people fail at using Titanium, they often lament, “But I thought Titanium was cross platform!!!” with the same anguish as Captain Kirk.
Titanium has been terribly misunderstood, and as a Titan, I feel the need to defend this technology and explain the right way to use it for success.
First off, the Appcelerator motto has always been, “write once, adapt everywhere”. If you’ve decided to use Titanium instead of the P-word that shall not be named (hint: PhoneGap), then congratulations, you’re on your way to building a truly native, cross platform app. In order to use Titanium the “right way”, however, you have to first understand what you’re getting with it. So, let’s take a short detour to what’s happening in Titanium “under the hood” before we explore how and why people are using it wrong.
Now, there are many components that are shared between the two platforms. Titanium is great if you’re writing an app where most of the features and components will be the same between the two (and that will probably be the case 90-95% of the time). But if you’re adding a component that exists on an iPhone but not on an Android app (one quick example that comes to mind is a button bar, which is two or more buttons that are connected, and share state for that component), and then you run that app on an Android device, it will throw an error, because there is no native Android Java code to build a button bar. To handle that, you must put branching code that executes certain portions of your code only if it’s running on iOS, versus when it’s running on Android.
Some other differences may not be so obvious, and could even change the user story of your app, and therefore force you to build an entirely new app, if you’re not careful. An example that comes to mind was when my team was building the parking app from the Denver Civic Hackathon of 2012 . We initially built our app with a map on each of two tabbed windows. It worked fine on the iPhone simulator, but when we tried to run it on an Android device, it crashed. It turned out that at the time, Android did not allow the display of two maps in an app. This was a native Android restriction, meaning that even if you built an Android app using Android Java, you would run into the same problem. We changed our user story to have only 1 map, and continued building out the rest of our app, testing on both platforms as we went. We were successful, and ended up building a fully functional app in Titanium, that ran on both on iPhone and Android. Had we not caught that problem early on, we would have had to rewrite that app entirely after we were done, or write two separate apps in Titanium, defeating the purpose of building one codebase. Now, with the current version of Google Maps, you can embed two or more maps in an Android app, but that would not have helped us back then.
By now, you might have guessed what’s the number one mistake people are making with Titanium. If you guessed that people are not using Titanium to build a cross platform app from the very beginning, you are right. If your goal is to have your app available on both platforms (which it probably is, if you’re using Titanium), then you need to architect, build, and test for both platforms from the very beginning. Because the Android emulator is such as pain in the butt (it’s extremely slow for one thing, but there are ways to improve that), a lot of people just rely on the iPhone simulator to test their apps. They’ll build their app all the way through just testing on iPhone/iPad, and then finally run it on the Android emulator or device, and are surprised when the whole thing fails.
Building an app for both platforms requires a commitment to learning the design patterns of both platforms. Become familiar with which functions are native to Android only or native to iOS only, and which functions they both share. I’ve put the Kitchen Sink (Appcelerator’s open source app that demonstrates all the features of the Titanium SDK) on both my Android and iOS test devices. If there’s any question of which component works on what, the Kitchen Sink usually has the answer. The Kitchen Sink is cross platform, so it will show both the features that the platforms have in common, plus Android-only features on the Android version, and iOS-only features on the iOS version. And don’t forget to test, test, test!
If I do all this extra architecture and testing to make sure my app is truly cross platform, then am I really saving any time and code by using Titanium, you may ask? That is a good question, and my answer to that is again, yes, but only if you follow my advice in this post. This isn’t a hard and fast rule, but I would say that if you use Titanium correctly, building a dual-platform baseline will take 1.3 – 1.5 times as long as building a single-platform baseline. If you build for one and then go back and “port” for the other, you could end up doubling the effort of a single-platform baseline, or worse. This defeats half the purpose of using Titanium! Note that one code baseline is always much easier to maintain than two, no matter how long it took to develop it.
Now, I’m not trying to be all doom and gloom about Titanium. It is an amazing technology, and I still stand behind it. Just remember that it’s not a quick fix and it’s not a magic bullet. But if you do it right, you will have a cross platform app, with the look and feel, performance, and user experience of the native platforms; as well as all the wonderful market opportunities that come with that. I still get a thrill when I build an app, even if it’s just a “Helloworld” app, install it on both my iPhone and Android devices, and marvel at how both apps are running the same code. If you respect Titanium and its power, and how it’s meant to be used, I hope you will experience that same feeling too!