Appcelerator Titanium is a popular
platform for developing mobile apps for more than one device operating system (OS)
excellent documentation and community resources.
If you’re used to writing
it’s easier to learn than the toolkits, languages, and development environments
that support the native OS platforms.
But developing with Titanium is
not the same as for the web — there are quirks and issues specific to each OS.
If you don’t know these quirks and don’t follow best practices, the end result will
likely be disappointing.
This article introduces Titanium’s Mobile Best Practices with a short tutorial on writing an iPhone app that
presents a table view with custom rows. I assume you have installed Titanium Studio
for the Mac after downloading from the Appcelerator Developers site. Registration is free.
Create the demo project
Open Titanium Studio and select New | Mobile Project from the File menu.
From the available templates, select Classic (Alloy is the other option) and Default
For project name enter Demo and for the
App Id enter com.mycompany.Demo.
new, classic Titanium mobile project will be created in your chosen workspace
the Editor window, there should be a Dashboard tab (if not, click the little
green shield icon in the lower right corner of the Studio next to your name). Find
where it says My Apps and click it; Safari will open Appcelerator’s web portal
for your apps. Click the App Details for your Demo. Figure A shows selections
for analytics, cloud, and enterprise extensions, as well as details of your
free subscription plan.
Go back to Titanium Studio and
double-click the tiapp.xml file in the App Explorer window to display the file
in the Editor window (Figure B). Tiapp.xml contains the configuration settings for the Demo app.
If you don’t plan to use
Appcelerator’s analytics service, you should replace true with false between
the analytics tags.
The iphone tags contain the orientation settings for the iPhone and the
iPad. If you want to add landscape orientation to the iPhone, copy the left and
right landscape orientation tags from
the iPad section into the iPhone orientations
Don’t pollute the global object
The main controller for the
Demo app is the app.js file. Double-click app.js in the App Explorer window to
display the file in the Editor window (Figure C).
Replace the default code with
the function shown in the figure. A self-calling function is used to start the
application window because it makes a closure that doesn’t pollute the global
object, available as this in app.js. The
function checks the mobile OS name so the application window that has iOS-specific
calls to the Titanium SDK is loaded.
Applications should use CommonJS modules
Create the ApplicationWindow.js
in the handheld/iphone folder (you may first have to create the handheld and
iphone folders). Display the file in the Editor window. The file shown in Figure D contains a
module for instantiating an iOS navigation window object. The navigation
window’s initial window is loaded from the TableWindow.js file. The module is
exposed to the outside world with the exports
The table view
Create the TableWindow.js file in
the handheld/iphone folder and display the file in the Editor window. The file shown in Figures E and F contains
a module for instantiating a window containing a table view.
Each row of the table view is created with the createTableViewRow API so it can be
customized. For iOS, it is
important to explicitly set the row’s height (do not use ‘auto’ or Ti.UI.SIZE)
and className properties for all rows that have the same layout.
It is also important to create a transparent view that
fills the entire row. With the touchEnabled
property of the row set to false, the transparent view will capture all single
tap events. Otherwise, the table will capture the single tap events and the
event will not include the tapped row’s index.
Add a listener for single tap events to the table. Only
one listener is needed for all the rows (do not add a listener to each row or
the button in each row). Because the table, row, transparent row view, and
button each have an objName property,
it will be included with the event’s source
property. If the objName is ‘button’,
a dialog is shown with the button title. Otherwise, the Detail Window is loaded
and opened in the navigation window. This window is loaded only when a row is
The Detail window
Create the DetailWindow.js file
in the handheld/iphone folder and display the file in the Editor window. The
file shown in Figure G contains a module for instantiating a window with a
label that displays the index of the row that was tapped.
Best practices for managing
memory include closing windows, nulling out references to objects, and removing
global event handlers when no longer used. It is also easy to create a memory
leak by adding an event handler to a UI object (e.g., a table) in a scope other
than where the object is declared. For example, it’s bad to declare a table
outside of a module’s exported function and add an event handler to the table
within that function.
Run the app
Assuming you have the Xcode tools installed and have added a
launch configuration for the iPhone simulator to the Demo project, it is easy
to run the simulator, or install onto a device, from Titanium Studio.
In the App Explorer window, click the Run icon and select
the iPhone simulator launch configuration. The first screen shot below shows
the Demo app after the button labeled H is tapped. The second screen shot below shows the detail window
after the row is tapped.
This simple demo app is hopefully
something you can build upon when developing a more complex Titanium mobile
app. In addition to the best practices, you should keep up to date with the
tips, tricks, and gotchas found in the forums and on developer blogs. Titanium
is always improving, and Alloy
is the next thing to consider.
Additional reading about Titanium
- Mobile Best Practices
- Appcelerator Blog
- Learning Titanium
- Appcelerator Developer Center
- Titanium tips and tricks thread
- Titanium Mobile – Gotchas
- About the Debug Perspective