Four Ways To Build A Mobile Application, Part 4: Appcelerator Titanium

Advertisement

This article is the last in a series of articles covering four ways to develop a mobile application. In previous articles, we covered how to build a tip calculator in native iOS1, native Android2 and PhoneGap3. In this article, we’ll look at another cross-platform development tool, Appcelerator Titanium.

PhoneGap enabled us to build a tip calculator app quickly and have it run on both the Android and iOS platforms. In doing so, we were left with a user interface (UI) that, while quite usable, did not offer quite the same experience as that of a truly native application. Our PhoneGap solution leveraged a Web view and rendered the UI with HTML5 and CSS3.

By contrast, Appcelerator Titanium applications render the UI using the platform’s native controls. Titanium is intended to provide the experience of a native UI, along with portability between the iOS, Android and BlackBerry platforms. Appcelerator plans to release support for Windows Phone and Windows 8 later this year4.

Here’s the Appcelerator Titanium version of our sample FasTip application running on both iOS and Android:

FasTip application on iOS.5
FasTip application on iOS. (Large preview6)

FasTip application on Android.7
FasTip application on Android. (Large preview8)

With Titanium, an application is written in JavaScript. However, instead of manipulating an HTML DOM, as would be done in a PhoneGap application, the JavaScript is interacting with Appcelerator Titanium’s API. Titanium provides UI objects for things like buttons, text fields, lists and so on, and these are backed by the mobile platform’s truly faithful representation of the respective native controls. In many cases, the code you write for one platform can run unmodified on other platforms as well. However, as we’ve seen with native iOS and Android’s different approaches to navigating screens (for example, ViewControllers with the NavigationController on iOS and Activities in Android), not all of these differences can be abstracted well. As such, even with Appcelerator, at least some parts of your code will have to be written specifically for each platform.

Appcelerator consists of a suite of products, including the Titanium SDK for building mobile applications, and some cloud services that can be used for the back end of the application. The products may be used independently of one another or in combination. The Titanium SDK and an integrated development environment (IDE) are offered free of charge for any commercial application. Appcelerator makes available at additional cost an Enterprise9 version that includes additional support, cloud services and analytics capabilities. Training courses and a certification program are also available for an additional fee.

A Eclipse-based IDE named Titanium Studio10 is offered by Appcelerator. This IDE contains a JavaScript editing environment, along with a source-level debugger.

Titanium Studio IDE overview.11
Titanium Studio IDE overview. (Large preview12)

As of the time of writing, no graphic layout tools exist that are akin to the ADT layout manager for Android or the StoryBoards and Interface Builder for iOS. With Titanium, the layout of screens is written either in JavaScript or in an XML definition language, as part of Appcelerator Titanium’s Alloy framework. Alloy is an application framework that allows you to specify the UI of an application in XML and apply styles to the controls in the project via a CSS-like syntax. I’ve included the code for both an Alloy and a Classic version of our application in the same GitHub repository13 that holds the code samples for the other articles in this series.

Starting Your First Project

Appcelerator Titanium and Titanium Studio are available free of charge. Appcelerator offers a “Quick Start14” document that fully covers the steps to get started. Just follow these steps to get Titanium’s tools:

  1. To use Titanium, you must create a free developer account15 on the Titanium website. Through this developer account, you will obtain the Titanium SDK and Titanium Studio IDE.
  2. Once you have a developer account, you’ll have access to Appcelerator’s developer resources16. Here, you’ll find a series of “Getting Started” links, including ones to obtain the tools for Mac, Windows and Linux.
  3. Just as with PhoneGap, you’ll have to install the native SDKs for the platforms you wish to support. However, Titanium Studio makes that easy. A Platform Configuration17 tool built right into Titanium Studio makes it easy to install and update the native SDKs:

    Install the native SDKs18
    Install the native SDKs. (Large preview19)

    Now you’re ready to create a project.

  4. From the “File” menu, choose “New” → “Mobile App Project.” This will open a dialog box that lets you choose an Alloy or Classic development project. As mentioned, Alloy is an application framework by Appcelerator that enables you to specify the UI of an application in XML and to use a CSS-like syntax to style the application. The Classic templates take an all-code approach. Appcelerator recommends Alloy for most new Titanium projects. Most of the examples in this article will use Alloy because I find its code structure to be more maintainable.

    Choose a development project.20
    Choose a development project. (Large preview21)

  5. Selecting the “Default Alloy” project will give you a simple project with one “Hello World” screen, a useful starting point. Clicking “Next” opens the next dialog:

    A simple project with as a useful starting point.22
    A simple project with as a useful starting point. (Large preview23)

    In the example above, we’ve filled in the fields for an app named “MySampleApp.” Once you click the “Finish” button, Titanium Studio will create the project’s directory structure and open it in the project explorer.

  6. Running the app is as easy as selecting a simulator in the device drop-down menu and pressing the “Run” button:

    run-on-ios-50024
    Running the app. (Large preview25)

  7. The “Run” button has a drop-down menu of its own that provides options for debugging and packaging your application for distribution.

Organizing An Appcelerator Project

For this article, we’ll focus on the Alloy version of the application. Its project structure looks like this:

Project Structure26
Project Structure

A project is a collection of XML, TSS (we’ll get to these later) and JavaScript files, along with any graphic assets required for the application. When the project is compiled for a platform, the compiler translates the XML and TSS files into JavaScript code and packages the code, along with the graphic assets, into a deployment package for the relevant mobile platform. The XML and TSS files are not interpreted at runtime; they’re there simply to save you the tedium of writing a lot of code for the layout and styles of the controls. Titanium’s documentation shows how the XML and TSS are mapped27 to JavaScript. If you’re familiar with Adobe Flex development, the XML files are handled much like MXML files.

Every project starts off with an index.xml file, which serves as the starting point of the application. Upon opening the index.xml file in the views directory, we see the following:

<Alloy>
  <Require id="calculator" src="calculator" platform="android"/>
  <NavigationWindow id="index" platform="ios">
    <Require src="calculator" id="calculator"/>
  </NavigationWindow>
</Alloy>

This markup tells the compiler to load the contents of calculator.xml into the main window. Note the platform="android" attribute; every element in Alloy may be decorated with a platform and/or formFactor attribute28 to indicate that the element is meant for a particular platform (Android, iOS, etc.) or form factor (handheld or tablet).

After the Require element for Android, we see the same Require element but wrapped in a NavigationWindow29 element. As mentioned, Android and iOS have different mechanisms for moving the user between screens. In this case, NavigationWindow corresponds to the UINavigationController that we used to build our native iOS application. Android does not have a corresponding navigation element, and so navigation is handled differently. Titanium’s SDK exposes both forms of navigation to the developer, rather than attempting to abstract the differences via some lowest-common-denominator approach. This provides more direct access to the native controls but requires the developer to deal with these differences. As a result, in several places in our code, we’ll have to account for the requirements of each platform.

For each view, we have a corresponding controller file. Here are the contents of index.js:

if (OS_IOS) {
  Alloy.Globals.navgroup = $.index;
}

if (OS_ANDROID) {
  $.calculator.getView().open();
} else {
  $.index.open();
}

This file begins with some code that checks special variables30 provided by Alloy to indicate the platform on which the application is running. For iOS, we assign a reference to the NavigationWindow object onto the Alloy.Globals object. Alloy.Globals is simply a common namespace where you can store objects that can be accessed anywhere in the application. In this case, we’re storing a reference to NavigationWindow so that we can access it anywhere in the app. The last section of code opens the controller that will display the main calculator view. For Android, we’ll open the view on the controller directly. For iOS, the view is in NavigationWindow, so we need to open NavigationWindow instead.

Defining The UI

On the first screen of our application, the UI is defined by the views/calculator.xml file. It contains elements to describe each TextField, Button, Label and so on on the screen.

<Alloy>
  <Window title="Alloy FasTip" backgroundColor="#fff">
    <!-- Android menu -->
    <Menu platform="android">
      <MenuItem
          onClick = "clickedSettings"
          title = "Settings"
          icon = "Ti.Android.R.drawable.ic_menu_preferences"
          showAsAction = "Ti.Android.SHOW_AS_ACTION_IF_ROOM" />
    </Menu>

    <!-- rightNavButton for platforms that support it -->
    <RightNavButton platform="ios">
      <Button id="settingsButton"
          onClick="clickedSettings"
          title="Settings" />
    </RightNavButton>

    <TextField id="billAmtTextField"
          top="40"
          width="146"
          height="35"
          textAlign="right"
          hintText="Bill amount"
          keyboardType="Ti.UI.KEYBOARD_DECIMAL_PAD"
          returnKeyType="Ti.UI.RETURNKEY_DONE" />

    <Button id='calcTipButton'
        onClick="clickedCalculate"
        title="Calculate Tip"
        top="100" width="122"
        class="primaryButton" />

    <View top="170" width="Ti.UI.SIZE" height="Ti.UI.SIZE">
      <Label left="13" width="124"
          top="0"
          textAlign="Ti.UI.TEXT_ALIGNMENT_RIGHT">
        Tip Amount:
      </Label>
      <Label id="tipAmtLabel" left="130"
          top="0" width="80"
          textAlign="Ti.UI.TEXT_ALIGNMENT_RIGHT">
        $0.00
      </Label>
      <Label left="13" width="124" top="30"
          textAlign="Ti.UI.TEXT_ALIGNMENT_RIGHT"
          class="totalAmt">
        Total Amount:
      </Label>
      <Label id="totalAmtLabel" left="130"
          top="30" width="80"
          textAlign="Ti.UI.TEXT_ALIGNMENT_RIGHT"
          class="totalAmt">
        $0.00
      </Label>
    </View>
  </Window>
</Alloy>

At the top of the file, we run into another difference between platforms. Android supports menus that, as we saw in the article on native Android, appear in the action bar on Android 4.x devices. This menu element describes a single menu option on this screen, the settings wrench.

Android Action Bar.31
Android Action Bar

<!-- Android menu -->
<Menu>
  <MenuItem
      onClick = "clickedSettings"
      title = "Settings"
      icon = Ti.Android.R.drawable.ic_menu_preferences
      showAsAction = Ti.Android.SHOW_AS_ACTION_IF_ROOM />
</Menu>

The menu element applies only to Android, so decorating this with a platform-specific attribute, such as platform="android", is not necessary. In iOS, this element will be ignored by the Alloy compiler.

To make the settings button appear in iOS, we need to add it to the iOS navigation controller’s button bar. This is accomplished with the following element, with an attribute that restricts it to iOS (platform="ios"):

iAndroid Navigation Controller32
Android Navigation Controller

<RightNavButton platform="ios">
  <Button id="settingsButton" onClick="clickedSettings"
      systemButton="Titanium.UI.iPhone.SystemButton.COMPOSE" />
</RightNavButton>

The systemButton attribute in the Button element above identifies one of iOS’ standard button styles. You could, of course, remove it and supply a text title or other suitable image if you desire.

Notice that in both cases, the menu item and the navigation button invoke the same function via the onClick attribute. The code for this screen is controlled by a JavaScript file with the same name as the .xml file. The Alloy framework refers to this as a controller, and by convention it is found in the controllers/calculator.js file. Alloy follows a set of conventions33 that govern where all files are located in the directory structure and how they relate to each other.

The first function in our calculator.js file handles the click event when the user taps the “Calculate tip” button:

function clickedCalculate(e) {
  var tipPct = Ti.App.Properties.getDouble('tipPct', .15);
  var billAmt = parseFloat($.billAmtTextField.value) || 0;
  var tipAmt = billAmt * tipPct;
  var totalAmt = billAmt + tipAmt;
  $.tipAmtLabel.text = '$' + tipAmt.toFixed(2);
  $.totalAmtLabel.text = '$' + totalAmt.toFixed(2);
  $.billAmtTextField.blur();
}

Ti.App.addEventListener('recalc', clickedCalculate);

To calculate the tip, we first attempt to retrieve the default tip percentage from Ti.App.Properties. This object is much like the objects we’ve used in the other three implementations: NSUserDefaults in iOS, SharedPreferences in Android and LocalStorage in PhoneGap. The controls that we defined in the calculator.xml file become properties in this controller, and we can reference them by using the $.<controlId> format. The calculation itself is very much like the code we used for PhoneGap — after all, this is still JavaScript.

In the calculator.js controller, we’ve also added an event listener via the Ti.App.addEventListener method. This enables our code to respond to events that occur elsewhere in the application. In this case, we’ll fire the recalc event from the settings screen when the user exits the window. This way, the calculator will always be up to date with the latest tip percentage. As we’ll soon see, the settings screen does not contain a direct reference to the calculator, so it cannot invoke methods on it directly. Using event listeners in this manner is a good way to decouple the controllers in our application, allowing them to continue communicating but without direct references to each other. These events come with some performance overhead, so use a direct callback if they’re going to fire in rapid succession.

Navigating Between Screens: Dealing With Platform Differences

The following code is run when the user clicks the “Settings” button:

function clickedSettings(e) {
  var settingsController = Alloy.createController('settings');
  var win = settingsController.getView();

  if (Alloy.Globals.navgroup) {
    Alloy.Globals.navgroup.openWindow(win);
  } else if (OS_ANDROID) {
    win.open();
  }
}

As soon as the user clicks the “Settings” button in the calculator view, the clickedSettings method on the calculator’s controller is invoked. Here, we create an instance of settingsController and get a reference to its view. The Alloy.Globals object is then checked for whether it contains a navgroup reference. Recall that this was established for iOS applications in the index.js file when our app first launched. Now we can use that navgroup to open the settings window. Android has no navgroup object, so we would just open the window directly.

The Settings Screen

The settings screen is defined in settings.xml, and its content is very similar to what we saw in calculator.xml:

<Alloy>
  <Window title="Settings" backgroundColor="#fff">
    <!-- Android menu -->
    <Menu platform="android">
      <MenuItem
          onClick="clickedDone"
          title="Done"
          icon = "Ti.Android.R.drawable.ic_menu_save"
          showAsAction = "Ti.Android.SHOW_AS_ACTION_IF_ROOM" />
    </Menu>

    <Label top="35">Set tip percentage</Label>

    <TextField id="tipPctTextField"
          top="72"
          width="60"
          height="35"
          textAlign="right"
          hintText="Tip %"
          keyboardType="Ti.UI.KEYBOARD_DECIMAL_PAD"
          returnKeyType="Ti.UI.RETURNKEY_DONE"
        ></TextField>
    <Label top="72" left="195">%</Label>

    <Button id='saveButton'
        onClick="clickedSave"
        title="Save Settings"
        top="120" width="130"
        class="primaryButton" ></Button>
  </Window>
</Alloy>

Just as with the calculator view, there are two different approaches to including a button in the action bar (in Android) or the navigation bar (in iOS). The “Done” button and “Save” button are wired to the relevant controller methods, as we’ll see next.

Upon the “Save” button being clicked, the following code is run in settings.js:

var tipPct = parseFloat( $.tipPctTextField.value );
if (tipPct > 0) {
  // Persist the new percentage value
  Ti.App.Properties.setDouble('tipPct', tipPct / 100);
  Ti.API.log('info', 'Settings saved');
  closeSettings();
} else {
  var dialog = Ti.UI.createAlertDialog({
        message: 'Enter a tip percentage greater than zero',
      ok: 'Try again',
      title: 'Invalid percentage'
      }).show();
}

To preserve the value of the tip percentage for future use, we use Ti.App.Properties.setDouble, which will persist the value between runs of our application. For debugging purposes, we’ll also log a message via Ti.API.log, which will write a message to the device log. This is essentially the same as writing a message to console.log() in a browser.

The next important section of code deals with how the window is closed:

function closeSettings() {
  Ti.App.fireEvent("recalc");
  var settingsWindow = $.getView();
  if (Alloy.Globals.navgroup) {
    Alloy.Globals.navgroup.closeWindow(settingsWindow, {animated:true});
  } else {
    settingsWindow.close();
  }
}

In this case, first, we’ll fire the recalc event that we established a listener for in the calculator controller earlier on. This will trigger the calculator to apply the new percentage value when the user leaves this screen. Just as we saw with opening the settings window, some platform-specific code is needed when the window is closed. The Alloy.Globals namespace is checked once again to see whether there is a navgroup for iOS. If so, we use it to close the window. On Android, we can close the window directly. Upon closing this window, the user will return to the previous calculator window and, because we’ve fired the recalc event, will see the tip calculation updated to reflect the newly saved percentage.

Styling Our Application

In the past, Appcelerator required the developer to programmatically define each control and its attributes. This was tiresome if you wished to change the style of an application. You might have needed to go back and change a lot of code. With the Alloy framework, Appcelerator has added Titanium style sheets34 (TSS). These work much like CSS in Web development. Each view and controller in an application has a corresponding TSS file, which allows you to adjust the style for that view in the application. In addition, the app.tss file governs the overall style of the whole application, allowing us to style the controls in all views of the application. The app.tss file is ideal for establishing consistency across views in an application. Here is the app.tss code for our application:

"Window": {
  backgroundColor:"#fff"
}

"Window[platform=android]": {
  navBarHidden: true
}

"Label": {
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  color: "#000"
}

"TextField": {
  color: "#000"
}

"TextField[platform=ios]": {
  paddingLeft:10,
  paddingRight:10,
  borderColor:"#000",
  borderRadius: "10",
  borderWidth: "1"
}

"Button": {
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  borderRadius: 15
}

".primaryButton": {
  backgroundColor: '#3883B5',
  color: '#fff'
}

The TSS entries above may be applied to Alloy elements such as the Window and TextField objects. They may also be applied to specific controls, via a class attribute that works just like the class attribute in HTML. Recall that a “Calculate tip” button was in our calculator.xml file:

“Calculate tip” button35
“Calculate tip” button

<Button id='calcTipButton' onClick="clickedCalculate"
    title="Calculate Tip"
    top="100" width="122"
    class="primaryButton" >
</Button>

This button has a class of primaryButton, which maps to the style defined in app.tss:

".primaryButton": {
  backgroundColor: '#3883B5',
  color: '#fff'
}

We’ve used the same class name for the “Save settings” button on the settings screen, and it will receive the same styles. In addition, the “Calculate tip” button has rounded corners because we’ve styled all of the buttons in our application to look so:

"Button": {
  width: Ti.UI.SIZE,
  height: Ti.UI.SIZE,
  borderRadius: 15
}

You may also specify styles based on platform. This TSS code applies only to TextFields in iOS:

“Bill amount” button36
“Bill amount” button


"TextField[platform=ios]": {
  paddingLeft:10,
  paddingRight:10,
  borderColor:"#000",
  borderRadius: "10",
  borderWidth: "1"
}

Alloy also allows you to create platform-specific folder names under the styles directory and obtain styles that way as well. In addition, you can create themes37 to apply different assets and styles based on the configuration of a particular build. Using a theme, you could load an entirely different set of assets, which would be useful if you’re working with different branding requirements from multiple clients.

Other Alloy Features

Our simple application does not require several of Alloy’s other features, such as models38 and collections39. These features were actually drawn from the popular Backbone.js40 library, which should make them familiar to many JavaScript developers. In addition, you can reuse visual components across applications with widgets41. A widget is self-contained and provides its own set of models, views and controllers, allowing it to be dropped into multiple applications.

Classic Appcelerator Applications

In the GitHub repository, I’ve included sample code for our FasTip application written in the Classic development style. We won’t go through all of the code here — just a few highlights to show how this approach differs from Alloy. For most projects, I’d recommend using Alloy. However, note that Alloy essentially creates a Classic Appcelerator application from your Alloy code. Understanding traditional Appcelerator development is important if you want to dynamically add or remove controls at runtime.

When a Titanium application starts, it runs the contents of the app.js file. In FasTip, we’re largely relying on the same app.js file that is created when a new project is initialized in Titanium Studio. Note that the following code identifies which platform the app is running on:

(function() {
  // Determine platform and form factor and render appropriate components
  var osname = Ti.Platform.osname,
    version = Ti.Platform.version,
    height = Ti.Platform.displayCaps.platformHeight,
    width = Ti.Platform.displayCaps.platformWidth;

  var isTablet = osname === 'ipad' ||
    (osname === 'android' && (width > 899 || height > 899));

The Ti.Platform.osname property provides the main clue as to whether we are running on an iPad, iPhone or Android device. You can see from this code that by using data provided by Ti.Platform, we can assume some things about the type of device that the app is running on. We saw the Require element used in Alloy to load one controller into another. Here’s an example done in straight code:

if (osname === 'iphone') {
Window = require('ui/handheld/ios/ApplicationWindow');
} else {
  Window = require('ui/handheld/android/ApplicationWindow');
}
new Window().open();

Notice that the code snippet above loads a particular version of the ApplicationWindow.js script based on the value of platform.

The following is a block of code to add some controls to a window. It shows how controls may be created programmatically without the use of Alloy.

var isAndroid = (Ti.Platform.osname === 'android');

var billAmtTextField = Ti.UI.createTextField({
  id: 'billAmtTextField',
  borderStyle: Ti.UI.INPUT_BORDERSTYLE_ROUNDED,
  keyboardType: Ti.UI.KEYBOARD_DECIMAL_PAD,
  returnKeyType: Ti.UI.RETURNKEY_DONE,
  hintText:'Bill amount',
  textAlign: Ti.UI.TEXT_ALIGNMENT_RIGHT,
  top:40,
  width:'146dp', height: '35dp',
  color:'#000'
});
if (isAndroid) {
  billAmtTextField.font = {fontSize: '12dp'};
}
self.add(billAmtTextField);

var calcBillButton = Ti.UI.createButton( {
  title: 'Calculate Tip',
  top:100,
  width:'122dp', height: '30dp',
  color:'#000'
});
if (isAndroid) {
  calcBillButton.font = {fontSize: '10dp'};
}
self.add(calcBillButton);

The self object above refers to the window, and self.add() is used to add each of the controls to the window. Specifying all of these attributes for every control that you add of a given type is tedious. Moreover, keeping the styles consistent in an app is difficult without the help of TSS style sheets, as in our Alloy example. In practice, if you do not use Alloy, then building controls from a JavaScript “factory pattern” would be better than calling the Ti.UI.create methods directly. This way, you would only have to change the factory methods to generate controls with different attributes.

Extending Titanium With Modules

While Titanium does a great job of providing much of the common functionality found in the mobile platforms that it supports, what if you need to access device features that are not directly offered by Titanium? In PhoneGap, the plugin system provides this capability. Titanium offers a similar system, called modules42, which enable your Titanium application to access native code. The Appcelerator Marketplace43 is a registry of both free and paid modules. In addition, a GitHub repository44 contains free open-source modules. You could, of course, write your own45 modules, too.

Deploying Your Application

Titanium Studio has a “Publish” option in the project explorer. Just right-click on the project and choose the appropriate publishing option:

Publish your application, Step 1.46
Publish your application, Step 1. (Large preview47)

As with any other development tool, you still need an account in the relevant app store to sell your application. Once you’ve chosen an option, the publishing dialogs will walk you through the process of signing the code and submitting it:

Publish your application, Step 2.48
Publish your application, Step 2. (Large preview49)

It’s convenient that this is built right into the Studio IDE, and the dialogs do a good job of walking you through the process. Titanium Studio’s documentation provides more details50 on the publishing process.

Appcelerator Cloud Services

While not the focus of this article, I should mention Appcelerator’s Cloud Services51 (ACS). These services are a separate offering from Titanium. They are server-based back-end services that can be used to store data for an application. At present, the services vary52 from photo storage to access control. Titanium exposes these services in the following ways:

A recent addition is Node.ACS57, which enables you to write custom NodeJS58 server-side applications. This is useful for encapsulating custom business logic on the server side. There are certainly alternatives to ACS, including Parse59 and StackMob60, but they don’t have the same level of integration with Appcelerator.

Learning Resources

A series of tutorials61 are available to get you up to speed. Appcelerator offers a page of training resources62, with many links on how to get started. It also offers a paid training63 and certification64 program for those who are interested in building skills in this way. The official blog65 is also a good way to stay up to date on the latest news about the platform.

In addition to Appcelerator-supplied resources, TiDev66 is an independent resource for Titanium-related articles. Another repository of Titanium modules resides at gitTio67, and Alloy-related components can be found at Alloy Love68

Appcelerator Titanium: Right For Your Project?

Like most tools, this one has its pros and cons. The promise of cross-platform development, with better user experience (UX) performance than an HTML-based solution like PhoneGap, is certainly attractive. However, as we’ve seen from the examples above, the framework cannot fully abstract all of the differences between platforms and still provide a native-like experience. As such, you’ll likely find yourself tailoring the view and controller code in your application to each platform.

Because they’re still writing the platform-specific code with Appcelerator’s API, a developer would find it much easier to leverage their skills across multiple platforms — they’d still be writing everything in JavaScript. For non-visual portions of an application, doing things like making AJAX calls from an Appcelerator app is quite simple, and unlike the fully native platforms, the JSON responses from typical REST-based services are directly understood by JavaScript. The native platforms require you to use a JSON parser to transform the REST responses into something that the native language can work with. Even if you wind up splitting the code for the Android and iOS views in your application, you would likely have to write the data model and business logic code only once. This single base of code could then be accessed from the platform-specific views in your application.

As with any tool from a third-party vendor, there may be some lag before a platform’s new features become available in Appcelerator’s platform. The development team at Appcelerator doesn’t get access to betas of the iOS and Android SDKs any earlier than other developers, so it will take time for a platform’s new features to get added to the product. If you need access to cutting-edge features as soon as they’re released in beta, then you’re better off with a purely native approach. Still, Appcelerator is generally proactive in making its tools compatible with the latest SDK releases, enabling developers to update their apps soon after a new version of a platform has been made available to the general public. Answers to most support-related questions can be found in Appcelerator’s own forums. By contrast, questions relating to fully native development and to PhoneGap are more widely covered on third-party websites such as StackOverflow.

Series Summary

We’ve seen how four different mobile technologies can be used to build the same application. A native application generally performs the best and provides the best access to a platform’s capabilities. Despite this, many enterprises are looking for solutions that run on multiple platforms.

PhoneGap is quite attractive to developers who have a strong background in HTML, CSS and JavaScript. It also offers a wide range of platform support, well beyond iOS and Android. As rendering performance and HTML5 compatibility improve on mobile devices, the gap in performance between native code and HTML narrows. Despite this, a UI implemented entirely in HTML and CSS might not be suitable for applications that are complex and have many animations. Still, in many cases, a properly written PhoneGap app provides a satisfying UX. The application’s UX designer and developer should work with the capabilities and limitations of the HTML5 platform, rather than try to force fit what could be accomplished in a purely native application.

Appcelerator requires the developer to learn its own API for UI controls — using, however, the native controls found on the platform. While the controls themselves will perform just as a native application’s would, all of the application logic will be running through a JavaScript engine. Thus, if the application performs a significant amount of calculations and data manipulation, then the performance would not match that of a truly native application. Moreover, Titanium abstracts the standard native controls into its own objects, meaning that not every property of the native controls would necessarily be exposed through Titanium. You could, of course, create modules to address this, but that would require additional effort. Depending on the number of modules necessary, the advantages of going with Titanium to begin with might be negated.

Your choice of development environment will depend largely on these factors:

  • Functional and UX requirements
    As stated above, some types of applications require native development. If you are competing with a number of native apps in the app store, then you might have to build a native app as well, just to match or exceed the UX of the competing applications. Perhaps you need access to a feature in the latest version of the operating system, one not yet supported by PhoneGap or Titanium. Working around this with the relevant plugin or module in PhoneGap or Titanium might be possible. But this assumes that a plugin exists or that you have enough experience in the native environment to write the plugin yourself.
  • Experience of the development team
    Many people are interested in PhoneGap or Appcelerator because they want to avoid learning a new language and platform. However, one still has to understand plenty of nuances in developing for the mobile Web (in the case of PhoneGap) or for Titanium. While you might not have to learn a new language, you will certainly have to learn new APIs and have at least some knowledge of the underlying platform. For instance, with PhoneGap, one needs to be aware of the limitations of animation performance (particularly in old versions of Android), the responsiveness of touch events and so on. Poor performance in PhoneGap applications is often the result of developers not paying attention to these issues. Developers must learn to respect the conventions of the platform on which their app will run or risk frustrating end users. Remember that these are mobile apps, not Web apps or desktop apps. The techniques for developing Web or desktop applications do not necessarily hold true for mobile applications.
  • Long-term maintenance
    Over time, an application will likely need changes. Do you have resources available in the given development technology to perform this maintenance? Are Appcelerator Titanium developers any more readily available than native developers or HTML5 developers conversant with PhoneGap?

We are fortunate to have several options for developing mobile applications. This overview has presented only four solutions. Other tools exist, such as Xamarin69’s products, which enable developers to write iOS, Android and Windows applications with .NET tools and C#. Developers of gaming applications might want to look at Corona SDK70. Or perhaps you don’t need an app at all. If the browser’s capabilities would suffice, then a mobile website might be appropriate.

Hopefully, this series has provided insight into some of the options available for building an application. Here’s wishing you well with whatever development platform you find best meets your needs.

(al, ml)

Footnotes

  1. 1 http://www.smashingmagazine.com/2013/11/22/four-ways-to-build-a-mobile-app-part1-native-ios
  2. 2 http://www.smashingmagazine.com/2014/01/10/four-ways-to-build-a-mobile-app-part2-native-android/
  3. 3 http://www.smashingmagazine.com/2014/02/11/four-ways-to-build-a-mobile-app-part3-phonegap/
  4. 4 http://www.appcelerator.com/blog/2014/01/windows-8-support-whats-going-on/
  5. 5 http://www.smashingmagazine.com/wp-content/uploads/2014/03/01-ios-screenshot.png
  6. 6 http://www.smashingmagazine.com/wp-content/uploads/2014/03/01-ios-screenshot.png
  7. 7 http://www.smashingmagazine.com/wp-content/uploads/2014/03/02-android-screenshot.png
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2014/03/02-android-screenshot.png
  9. 9 http://www.appcelerator.com/plans-pricing/
  10. 10 http://www.appcelerator.com/titanium/titanium-studio/
  11. 11 http://www.smashingmagazine.com/wp-content/uploads/2014/03/03-titanium-studio-ide.jpg
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2014/03/03-titanium-studio-ide.jpg
  13. 13 https://github.com/ptraeg/mobile-apps-4-ways
  14. 14 http://docs.appcelerator.com/titanium/latest/#!/guide/Quick_Start-section-29004949_QuickStart-LaunchingTitaniumStudio
  15. 15 https://my.appcelerator.com/auth/signup
  16. 16 https://my.appcelerator.com/resources
  17. 17 http://docs.appcelerator.com/titanium/latest/#!/guide/Installing_Platform_SDKs-section-29004842_InstallingPlatformSDKs-StudioPlatformConfigurationTool
  18. 18 http://www.smashingmagazine.com/wp-content/uploads/2014/03/04-install-sdk.png
  19. 19 http://www.smashingmagazine.com/wp-content/uploads/2014/03/04-install-sdk.png
  20. 20 http://www.smashingmagazine.com/wp-content/uploads/2014/03/05-newapp-step1.png
  21. 21 http://www.smashingmagazine.com/wp-content/uploads/2014/03/05-newapp-step1.png
  22. 22 http://www.smashingmagazine.com/wp-content/uploads/2014/03/06-newapp-step2.png
  23. 23 http://www.smashingmagazine.com/wp-content/uploads/2014/03/06-newapp-step2.png
  24. 24 http://www.smashingmagazine.com/wp-content/uploads/2014/03/07-run-on-ios.png
  25. 25 http://www.smashingmagazine.com/wp-content/uploads/2014/03/07-run-on-ios.png
  26. 26 http://www.smashingmagazine.com/wp-content/uploads/2014/03/08-directory-structure.png
  27. 27 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Concepts-section-34636240_AlloyConcepts-AlloyandtheTitaniumSDK
  28. 28 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_XML_Markup-section-35621528_AlloyXMLMarkup-ConditionalCode
  29. 29 http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.UI.iOS.NavigationWindow
  30. 30 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Controllers-section-34636384_AlloyControllers-ConditionalCode
  31. 31 http://www.smashingmagazine.com/wp-content/uploads/2014/03/09-android-actionbar.png
  32. 32 http://www.smashingmagazine.com/wp-content/uploads/2014/03/10-ios-navcontroller.png
  33. 33 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Concepts-section-34636240_AlloyConcepts-ConventionoverConfiguration
  34. 34 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Styles_and_Themes-section-35621526_AlloyStylesandThemes-TitaniumStyleSheets
  35. 35 http://www.smashingmagazine.com/wp-content/uploads/2014/03/11-calctip-button.png
  36. 36 http://www.smashingmagazine.com/wp-content/uploads/2014/03/12-bill-amount.png
  37. 37 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Styles_and_Themes-section-35621526_AlloyStylesandThemes-Themes
  38. 38 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Models
  39. 39 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Collection_and_Model_Objects-section-36739589_AlloyCollectionandModelObjects-Collections
  40. 40 http://backbonejs.org/
  41. 41 http://docs.appcelerator.com/titanium/latest/#!/guide/Alloy_Widgets
  42. 42 http://docs.appcelerator.com/titanium/latest/#!/guide/Using_Modules
  43. 43 https://marketplace.appcelerator.com/home
  44. 44 https://github.com/appcelerator/titanium_modules
  45. 45 http://docs.appcelerator.com/titanium/latest/#!/guide/Extending_Titanium_Mobile
  46. 46 http://www.smashingmagazine.com/wp-content/uploads/2014/03/13-publish-app-step1.png
  47. 47 http://www.smashingmagazine.com/wp-content/uploads/2014/03/13-publish-app-step1.png
  48. 48 http://www.smashingmagazine.com/wp-content/uploads/2014/03/14-publish-app-step2.png
  49. 49 http://www.smashingmagazine.com/wp-content/uploads/2014/03/14-publish-app-step2.png
  50. 50 http://docs.appcelerator.com/platform/latest/#!/guide/Packaging_Titanium_Applications
  51. 51 http://www.appcelerator.com/cloud/
  52. 52 http://www.appcelerator.com/cloud/key-features/
  53. 53 http://docs.appcelerator.com/cloud/latest/#!/guide/titanium
  54. 54 http://docs.appcelerator.com/cloud/latest/#!/guide/ios
  55. 55 http://docs.appcelerator.com/cloud/latest/#!/guide/android
  56. 56 http://docs.appcelerator.com/cloud/latest/#!/guide/rest
  57. 57 http://docs.appcelerator.com/cloud/latest/#!/guide/node
  58. 58 http://nodejs.org/
  59. 59 https://parse.com/
  60. 60 https://www.stackmob.com/
  61. 61 http://bit.ly/TYZEGq
  62. 62 http://training.appcelerator.com/training-resources
  63. 63 http://training.appcelerator.com/
  64. 64 http://training.appcelerator.com/get-certified
  65. 65 http://www.appcelerator.com/blog/
  66. 66 http://www.tidev.io/
  67. 67 http://gitt.io/
  68. 68 http://alloylove.com
  69. 69 http://xamarin.com/
  70. 70 http://www.coronalabs.com/products/corona-sdk/

↑ Back to topShare on Twitter

Peter Traeg is a Solutions Architect at Universal Mind where he brings his broad base of technical and business consulting skills to work for our clients. With 25+ years of experience in the application development field, Peter has worked on a wide range of applications from data warehousing to online photo sharing sites. At the Eastman Kodak Company he made extensive use of Flex, AIR, HTML5, iOS, and Android technologies to help Kodak customers share their memories across a wide range of devices.

Peter is active in several development user groups where he regularly speaks on web and mobile application development technologies. When he is not experimenting with his seemingly ever growing list of mobile devices, you can find him engaging in activities such as photography, cycling, and spending time with his family in Rochester, NY.

Advertising
  1. 1

    Jon Hobbs-Smith

    March 10, 2014 4:37 am

    4 great articles. I’d love to see a 5th part about Xamarin though as that’s the one I’m currently considering using (c# background).

    0
  2. 2

    “However, as we’ve seen from the examples above, the framework cannot fully abstract all of the differences between platforms and still provide a native-like experience. As such, you’ll likely find yourself tailoring the view and controller code in your application to each platform.”

    Who ever said you should fully abstract platform differences? iOS and Android are different systems with distinct UXes and user expectations. Android users don’t want iOS apps and iOS users don’t want Android apps. Regardless of the development tool you choose, you should be tailoring your app to fit the target operating system.

    1
    • 3

      Tim, thanks for your comment. I agree that in most cases you will want to follow platform guidelines and vary the user experience per platform conventions. As a matter of comparison, in the jQuery Mobile examples I offered for the PhoneGap article, the same user experience was provided on both platforms. In that article I pointed out the potential issues with providing the identical user experience on both platforms. jQuery Mobile is an example where the platform differences are fully abstracted, and the consequence is the identical experience on each platform.

      If developers truly wish to adhere to the unique user experience on each platform they must be prepared to write some platform specific code. I did not intend for this be seen as a deficiency of Appcelerator, but rather the acknowledgement that a cross-platform framework cannot be expected to “magically” abstract all platform differences.

      1
  3. 4

    Boydlee Pollentine

    March 10, 2014 6:53 am

    If you like the idea of Titanium but don’t know how to get started, we’re running a series of events around the globe focusing on Titanium development called tiConf (http://ticonf.org) including some workshop days. We’d love to see you there.

    1
  4. 5

    All this effort wasted on a bad product like titanium. Never heard a single dev say “titanium was the right choice”.

    Stay away, this product is such a bad idea the words fail me. There’s isn’t a single good reason to build anything in that ridiculous technology.

    FULL DISCLOSURE: I used to work for Sencha but I don’t have a horse in this race anymore. I simply despise Titanium as a concept and in practice.

    -3
    • 6

      Why? Can you explain your thoughts?

      0
      • 7

        I’m not going to waste anymore time speaking about Appcelerator, somebody else did a good job at explaining the problem before.

        This is a little old but still valid: http://usingimho.wordpress.com/2011/06/14/why-you-should-stay-away-from-appcelerators-titanium/

        Google a little and you will find TONS of similar stories.

        -1
        • 8

          Luca

          I am a mobile developer, I now only use Appcelerator Titanium. If coded correctly it is an ideal solution for us to use.

          I am very surprised by your broad statement, that not a single dev has ever said use Titanium.

          It is a development framework, and like every tool, you have to evaluate the pro’s and con’s as to if it is the right choice for the project being considered.

          We use it extensively for our enterprise applications, and it works incredibly well. It is a lot quicker for cross platform development, than native code and as I have said if used for the right application it performs really well.

          I can only guess that you have not visited Titanium recently and are very biased against what is a very good tool.

          And as you have put your full disclosure, I do not work for Appcelerator, this is a technology I used for a specific project initially, and I have produced quite a few very responsive and business critical applications for very large blue chip companies. I have been coding for over 25yrs, and have 2 books published on the platform.

          1
      • 9

        Owen,

        He won’t elaborate because he’s a troll. Citing articles from years ago. Clearly has. Hatred of Titanium and doesn’t have any real evidence.

        Moron.

        0
    • 10

      Matt Wohlstadter

      March 13, 2014 7:12 am

      Titanium has gotten the job done for me a number of times on several projects. Though it has a steep learning curve on certain parts of the application, if you have a fundamental knowledge of Javascript and are willing to learn the API’s you will be fine.

      1
    • 11

      Jason van der Zeeuw

      March 13, 2014 3:16 am

      I’m just about to use Titanium, why would you discourage Titanium?
      I’d love to here your arguments.

      0
      • 12

        More material:

        http://pasamio.com/2011/07/02/a-few-months-with-titanium-appcelerator/

        http://enricoangelini.com/2012/5-pros-and-cons-of-appcelerators-titanium/

        http://www.jacobsingh.name/content/appcelerators-titanium-truncated-review

        Bottom line: Titanium has way more problems than I can list in a lifetime, it’s buggy, tools are unstable, it requires a LOT of extra work to make apps truly cross platform which negates the supposed productivity increase, the apps always turn out ugly (for a bunch of reasons I won’t go into now) and at the end of the day, it’s just a good prototyping tool, but you’re a moron if you use it for production work.

        Every major company that adopted Titanium in the past has now walked back on that decision and rebuilt their stuff either for the web on Cordoba / Phonegap or natively.

        -5
        • 13

          Malcolm Hollingsworth

          March 14, 2014 5:06 am

          I respect your opinion – just a shame it is backed up by articles posted 2, 3 and 4 years ago and nothing offering a balanced view.

          Appcelerator is a very powerful tool and when used in the right hands is an exceptional solution for most apps. There are gaps in the built-in API which is why you can create native modules to bridge the gap.

          My biggest concern is when the phrase “cross platform” is so often incorrectly confused with “identical UI” – this is irrespective of native UI guidelines.

          Platforms have many common UI elements and internal processes – but when they differ, good developers know that the solutions should be tailored to those platform guidelines. I am not sure why pretending that every device is the same irrespective of the wishes of those platforms is respectful to the user or the platform itself.

          2
        • 14

          OK your statement

          “Every major company that adopted Titanium in the past has now walked back on that decision and rebuilt their stuff either for the web on Cordoba / Phonegap or natively.”

          Complete and utter RUBBISH.

          You obviously are biased and have no actual idea what Titanium can do, and how to do it.

          Yes I’m expecting a flame war here, but you are wrong in your assessment and wrong in your statements.

          I think before you make wide sweeping statements, consider the fact that I work for a multi million pound company, who only use Titanium, I hang around the titanium community, so I am better placed than you to comment on it’s usage, It’s usage is increasing greatly.

          I am not anti native code, nor am I anti Phonegap, but Titanium is the right tool for the applications we are developing, and as for you earlier comments about the apps being ugly, thats not a platform issue that’s a designer / developer issue.

          2
        • 15

          I disagree. At my company we started using PhoneGap, and walked away from it because we needed animation-heavy performance and it just wouldn’t do. While Titanium isn’t perfect (nothing is), with about 2-4 programmers we have managed to deploy and publish an iOS (iPhone and iPad) app and we are currently adapting it to Android, which is taking us little more than a month.

          The first article you linked to is from 2011, and features comments from people like Tony Lukasavage, who later started working at Appcelerator and is one of the main evangelists for Titanium now. Titanium has changed a lot since the date that article was written. I personally recommend it if you have no experience with native iOS and Android code.

          3
        • 16

          Tony Lukasavage

          April 8, 2014 9:53 am

          This is what happens when you base your opinions on someone else’s myopic opinions from 2-4 years ago… high-level, misguided, utter falsehoods.

          To give a frame of reference, your lambasting is roughly like judging the current viability of node.js based on version 0.4, like Ted Dzubia did. You remember seeing the “node.js is cancer” post in 2011, don’t you? Having trouble finding a non-cached link to it? That’s because the stark and obvious improvements in node.js have rendered his ill-conceived opinions to be no longer applicable. The only difference between him and the authors of the articles you cite is that he had the integrity to take his article down when it no longer applied.

          You may have legitimate issues with the current state of Titanium development. Despite massive improvements in features, stability, performance, and tooling since the publishing of the articles you cite, we’re still not perfect and never will be. I don’t know what your current gripes with Titanium might be. But then again, neither do you.

          6
    • 17

      > Never heard a single dev say “titanium was the right choice”.

      I guess you might need to open your ears and start counting since in this thread there are 3 devs saying so and if you would emerge yourself in our 550k+ community I think you’d find a few more ;)

      2
    • 18

      I recommended someone use Titanium just the other day after giving a session at a local code camp. I just finished a contract where we used Titanium and am being recruited for help on another.

      0
  5. 19

    There is absolutely no problem with Titanium – I’ve been using it for years to build apps on iOS and Android without a problem. Unfortunately Titanium isn’t good enough to let bad developers get away it – which is more than common with JavaScript.

    I’m developing apps in Titanium that are performing as fast as “native” apps, much faster than PhoneGap or web based alternatives and have customers that are VERY happy with the result.

    In fact, I’d go so far as to say “titanium was the right choice”.

    2
  6. 20

    Ive used Titanium on a number of projects and the tools have become more stable and with the use of Android Emulators like GenyMotion the workflow has become slicker and easier to use.

    The old days of SDK 2 where a little buggy to say the least but with the advent of Alloy it has become a better tool to play with. I agree getting the UI consistent across Android and iOS can be a little bit of a pain sometimes but there are ways around it.

    The Q&A forums are always a good source of information and a number of good resource blogs exisit to help you with development.

    The links @Luca has cited date back to 2010 and the most recent being 2012. I would say give it try if you are comfortable with Javascript.

    As regards App’s looking poor I think that’s down to poor use of UI – Im not saying Im a great UI designer but this app doesnt look too bad – http://www.clark-studios.co.uk/apps/uk-stableford-golf-calculator/ – Admitley it’s only iOS but converting it to Android would not take too much work using the same interface.

    Native will always the best option but if your like me and don’t have the time to learn Objective C or Java and know Javascript then it’s a winner. I cant say I have use Phonegap so I can’t comment on the comparison between the two but I will stick with Titanium.

    0
  7. 21

    Luca, wow.

    Titanium apps are ugly?

    Every major company who has gone to Titanium has gone back?

    I think you should give some examples / evidence (if you have the time – don’t want you to waste a lifetime) or are you just trolling?

    Oh And how’s the weather in Cordoba?

    0
  8. 22

    Thanks for the article!

    Just wondering why you chose to put the positioning code in the view rather than in the tss files?

    0
  9. 23

    Excelent article!! You miss Unity 3D as the main alternative to Corona SDK but these products needs another article.

    0
  10. 24

    how can i change icon i try but i get error and the color of the action bar

    0
  11. 25

    The truth is… Titanium is such as amazing platform, it should be kept a secret!

    Been developing for Titanium for 3 years, published solid, native, well designed apps for each platform & looking forward to the TiConf in NY in May :)

    0
  12. 26

    While I don’t agree with Luca’s delivery on the topic, I agree that any cross platform / one size fits all solution is great in concept but very rarely ideal. Here’s my gripes as a native app developer on both iOS and Android platforms:

    – The pace that the platforms get updated is so swift(pun intended) that any hybrid solution will always struggle to just meet the curve.

    – As a previous web guy, the hybrid solution code usually looks like a bunch of css webkit hacks all strung together in a very hard to read web of if statements and logic trees. This in itself is not a bad thing but it goes against good practice of making your code readable and easy to maintain.

    – Performance matters. No matter how good the hard ware gets, the software will match it in its native complexity and functionality. I can’t stress enough how important this is, when you have two apps that look exactly the same with same behavior I can bet that the average user will prefer the native version vs the “clunky feeling”(actual user response in my testing) hybrid app.

    – Learning native development is not as hard as it’s made out to be. There are TONS of resources and very large community on both sides that is very willing to help.

    – Both Mobile companies spend millions of dollars on developing a fully fledged and test sdk for developers. They want developers to use their tools. They offer a supreme pizza with all the trimmings that will please everyone. Most hybrid solutions offer burnt cheese pizza that gets staler by the minute. (Just had to do this one;)

    0
  13. 27

    I have developed an internal, home grown Lua platform with native binding with Java for Android, Objective-C for iOS and C#, WPF to Windows. There are tons of work involved, especially making the APIs that we promote as cross-platform, including wrapping for each platform, for every SDK features promised. Later we dropped building home grown system, instead adapter Xamarin for our enterprise customers. At least, we leave the cross platform capabilities to expert teams like Xamarin and we focus on application development.

    Right now, we use Titanium for another start-up, building application from scratch. Titanium is definitely better for people who don’t want to code in Native Technologies like Android/Java, iOS/Objective-C. While doing the development, I see the API design, workarounds, I understand the pain of the developers. I don’t think, anyone can do the better job here in cross platform other than Titanium developers.

    My concerns is all around Titanium eco-system, at least, I don’t see much support on their Q/A sections, not well developed market place, couple of modules developed, but not seems to be widely popular.

    If you read Titaninum blogs and branding, they tried pushing the platform for a price, then they try to push it as Mobile backend platform, Analytics and now with Enterprise. To me, they are trying to adapt various business model around the system, still not yet successful. Appcelerator trying new Ti.NEXT to get the speed closer to native. Windows native support is not yet completed, their might be delay, adding a 3rd platform shall make more complexities with respect to cross-platform native support and stability.

    We use free Titanium platform, without paying a penny, as a cross platform, they do a great job. They have to deal merciless iOS SDK, clueless Android SDK, mindless Windows SDK + open Web to make everything correct. That means Appcelerator has more challenges itself now and in future.

    To me, what they missed is eco-system, like HTML5 world has got over it. Might be the reason that enterprise developers don’t participate much in forums to help others like other open-source developers around cordova-phonegap platforms.

    We research Ionic, HTML5 framework going forward, still waiting to hear what Appcelerator is going to say about Windows support and future direction.

    1
  14. 28

    Titanium app development is becoming popular for developing cross platform mobile apps. There are several benefits of Titanium app development that makes it a trusted choice of many users. – http://bit.ly/1v5Dffq

    0
  15. 29

    Great article, but it should be noted that a Mac is required to do iOS development with Titanium. Windows and Linux do not get the iOS SDK.

    “Due to Apple’s license agreement, iOS applications may only be developed on Apple hardware.”
    http://docs.appcelerator.com/titanium/3.0/#!/guide/Titanium_Compatibility_Matrix

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top