Cloud-enabling Your Apps

(For more resources related to this topic, see here.)

Which cloud services can you use with Titanium?

Here is a comparison of the services offered by three cloud-based providers who have been proven to work with Titanium:

Appcelerator Cloud Services



Customizable storage




Push notifications












Link with Facebook/Twitter account




User accounts




The services offered by these three leading contenders are very similar. The main difference is the cost. Which is the best one for you? It depends on your requirements; you will have to do the cost/benefit analysis to work out the best solution for you.

Do you need more functionality than this? No problem, look around for other PaaS providers. The PaaS service offered by RedHat has been proven to integrate with Titanium and offers far more flexibility. There is an example of a Titanium app developed with RedHat Openshift at

It doesn't stop there; new providers are coming along almost every month with new and grand ideas for web and mobile integration. My advice would be to take the long view. Draw up a list of what you require initially for your app and what you realistically want in the next year. Check this list against the cloud providers. Can they satisfy all your needs at a workable cost? They should do; they should be flexible enough to cover your plans. You should not need to split your solution between providers.

Clouds are everywhere

Cloud-based services offer more than just storage.

Appcelerator Cloud Services

Appcelerator Cloud Services ( ACS) is well integrated into Titanium. The API includes commands for controlling ACS cloud objects.

In the first example in this article we are going to add commentary functionality to the simple forex app. Forex commentary is an ideal example of the benefits of cloud-based storage where your data is available across all devices. First, let's cover some foreground to the requirements.

First, let's cover some foreground to the requirements.

The currency markets are open 24 hours a day, 5 days a week and trading opportunities can present themselves at any point. You will not be in front of your computer all of the time so you will need to be able to access and add commentary when you are on your phone or at home on your PC. This is where the power of the cloud really starts to hit home. We already know that you can create apps for a variety of devices using Appcelerator. This is good; we can access our app from most phones, but now using the cloud we can also access our commentary from anywhere. So, comments written on the train about the EURUSD rate can be seen later when at home looking at the PC.

When we are creating forex commentary, we will store the following:

  • The currency pair (that is EURUSD)

  • ‹ The rate (the current exchange rate)

  • The commentary (what we think about the exchange rate)

We will also store the date and time of the commentary. This is done automatically by ACS. All objects include the date they were created.

ACS allows you to store key value pairs (which is the same as Ti.App.Properties), that is AllowUserToSendEmails: True, or custom objects. We have several attributes to our commentary post so a key value pair will not suffice. Instead we will be using a custom object.

We are going to add a screen that will be called when a user selects a currency. From this screen a user can enter commentary on the currency.

Time for action – creating ACS custom objects

Perform the following steps to create ACS custom objects:

  1. Enable ACS in your existing app. Go to tiapp.xml and click on the Enable... button on the Cloud Services section. Your project will gain a new Ti.Cloud module and the ACS authentication keys will be shown:

  2. Go to the cloud website,, find your app, and select Manage ACS. Select Development from the selection buttons at the top.

  3. You need to define a user so your app can log in to ACS. From the App Management tab select Users from the list on the right. If you have not already created a suitable user, do it now.

  4. We will split the functionality in this article over two files. The first file will be called forexCommentary.js and will contain the cloud functionality, and the second file called forexCommentaryView.js will contain the layout code. Create the two new files.

  5. Before we can do anything with ACS, we need to log in. Create an init function in forexCommentary.js which will log in the forex user created previously:

    function init(_args) { if (!Cloud.sessionId) { Cloud.Users.login({ login: 'forex', password: 'forex' }, function (e) { if (e.success) { _args.success({user : e.users[0]}); } else { _args.error({error: e.error}); } }); }

    This is not a secure login, it's not important for this example. If you need greater security, use the Ti.Cloud.Users. secureLogin functionality.

  6. Create another function to create a new commentary object on ACS. The function will accept a parameter containing the attribute's pair, rate, and commentary and create a new custom object from these. The first highlighted section shows how easy it is to define a custom object. The second highlighted section shows the custom object being passed to the success callback when the storage request completes:

    function addCommentary(_args) { // create a new currency commentary Cloud.Objects.create({ classname: className, fields: { pair: _args.pair, rate: _args.rate, comment: _args.commentary } }, function (e) { if (e.success) { _args.success(e.forexCommentary[0]); } else { _args.error({error: e.error}); } }); }

  7. Now to the layout. This will be a simple form with a text area where the commentary can be added. The exchange rate and currency pair will be provided from the app's front screen. Create a TextArea object and add it to the window. Note keyboardType of Ti.UI.KEYBOARD_ASCII which will force a full ASCII layout keyboard to be displayed and returnKeyType of Ti.UI.RETURNKEY_DONE which will add a done key used in the next step:

    var commentary = Ti.UI.createTextArea({ borderWidth:2, borderColour:'blue', borderRadius:5, keyboardType: Ti.UI.KEYBOARD_ASCII, returnKeyType: Ti.UI.RETURNKEY_DONE, textAlign: 'left', hintText: 'Enter your thoughts on '+thePair, width: '90%', height : 150 }); mainVw.add(commentary);

  8. Now add an event listener which will listen for the done key being pressed and when triggered will call the function to store the commentary with ACS:

    commentary.addEventListener('return', function(e) {forex.addCommentary({ pair: thePair, rate: theRate, commentary: e.value}) });

  9. Finally add the call to log in the ACS user when the window is first opened:

    var forex = require('forexCommentary'); forex.init();

  10. Run the app and enter some commentary.

What just happened?

You created functions to send a custom defined object to the server. Commentary entered on the phone is almost immediately available for viewing on the Appcelerator console ( and therefore available to be viewed by all other devices and formats.

Uploading pictures

Suppose you want to upload a picture, or a screenshot? This next example will show how easy it is to upload a picture to ACS.

Time for action – uploading a photo to the cloud

Perform the following steps to upload a photo to the cloud:

  1. Create a new project by navigating to File | New | Titanium Project. Select the Default Project template.

  2. Enable ACS in your existing app. Go to tiapp.xml and click on the Enable... button in the Cloud Services section.

  3. Go to the cloud website at find your new app and select Manage ACS. Select Development from the selection buttons at the top.

  4. You need to define a user so your app can log in to ACS. From the App Management tab select Users from the list on the right. If you have not already created a suitable user, do it now.

  5. We will split the functionality in this article over two files, the cloud functionality in cloud.js and the usual layout items in app.js.

  6. First create the layout in app.js. This will be a simple button and image view will allow the user to upload a photo from the photo gallery when the button is clicked. The image view will show the selected photo:

    var win1 = Titanium.UI.createWindow({ backgroundColor:'#fff' }); var options = Ti.UI.createView({layout: 'vertical'}); var sendPhoto = Ti.UI.createButton({title: 'Send photo to the cloud'}); var thePhoto = Ti.UI.createImageView({height: '30%', width: '30%'}); options.add(sendPhoto); options.add(thePhoto); win1.add(options);;

  7. Add a link to the cloud.js file where the cloud functionality will be stored. Add these lines to the top of app.js file:

    var upload = require('/cloud'); upload.init();

  8. Add an event listener to show the photo gallery that will be called when the button is pressed:

    sendPhoto.addEventListener('click', function(e) { Ti.Media.openPhotoGallery({ autoHide: true, mediaTypes: [Ti.Media.MEDIA_TYPE_PHOTO], success: function(e) {showPhoto(e); sendPiccyToCloud(e)} }); });

  9. Add the showPhoto function to set the image view to the photo returned from the photo gallery:

    function showPhoto(_args) { thePhoto.setImage(; }

  10. Add the function that will send the photo to the cloud. This function will first write the photo to a file before uploading as the ACS picture upload function can only work with files and not blob data:

    function sendPiccyToCloud(_args) { // first we need to write out a file of the piccy var file = Ti.Filesystem.getFile(Ti.Filesystem. applicationDataDirectory, 'cloudThis.png'); file.write(; // then send this file to the Cloud upload.sendPiccy(; file = null; }

  11. Create the cloud.js file by navigating to File | New | File. Add the following initialization function to the file. This function will log in to the ACS cloud services with the username and password created in step 4:

    var Cloud = require('Ti.Cloud'); //login as the cloud user.... function init(_args) { if (!Cloud.sessionId) { Cloud.Users.login({ login: 'pic', password: 'piccy' }, function (e) { if (e.success) { _args.success({user : e.users[0]}); } else { _args.error({error: e.error}); } }); } }; exports.init = init;

  12. Now add the function that uploads the picture to ACS. Remember that the picture must be a file:

    function sendPiccy(_args) { // create a new photo Cloud.Photos.create({ photo: Ti.Filesystem.getFile(Ti.Filesystem. applicationDataDirectory+'/'+_args) }, function (e) { if (e.success) { var photo =[0]; alert('Success:\n' + 'id: ' + ); } else { alert('Error:\\n' + ((e.error && e.message) || JSON.stringify(e))); } }); } exports.sendPiccy = sendPiccy;

  13. Run the app!

What just happened?

You created an app that allows the user to upload a picture from the photo gallery to ACS. When the app is run, you are presented with a screen with a single button. Pressing this button opens up the photo gallery; you then select a picture and it is uploaded to ACS and can be seen from the ACS web interface as shown in the following image:

The power of the cloud! Now we move on to the next example where we display the objects we are creating.

Photos can be downloaded from ACS using the same query functionality as shown in the next example. See!/api/Titanium.Cloud.Photos for an example.

Fetching ACS stored content

For this next example we will return to the forex commentary app that was created earlier in the article. It's all well and good storing the commentary, but we also need a way to look at it. This next simple example will show how to create a panel to show the last three commentary entries across all currency pairs.

Time for action – creating a panel to show commentary entries

You need to have completed the last example before starting this example. It's no use trying to fetch ACS content without storing some first. Perform the following steps to create a panel showing commentary entries:

  1. Ensure that the following calls are included:

    var forex = require('forexCommentary'); forex.init();

  2. We need a function that will get the last three custom objects from ACS. The query command has two parameters. The first defines the query, and the second is where you specify what you want to do with the results that are returned. In the following example, the object returned is called forexCommentary:

    function getLast3Comments(_args) { Cloud.Objects.query({ classname: 'forexCommentary', limit: 3, order : '-created_at' }, function (e) { if (e.success) { _args.success(e.forexCommentary); } else { _args.error({error: e.error}); } }); };

    It is very easy to change the query. For example if we only wanted to get the commentary for euros to dollars (EURUSD), we would add:

    order : '-created_at', where : {pair : 'EURUSD'}


  3. Now create a table view to display the commentary and add it to the window:

    var latestCommentary = Ti.UI.createTableView({}); mainVw.add(latestCommentary);

  4. Create a function that creates the table view layout. This function will parse the forexCommentary object returned from ACS, grabbing the elements we wish to use to create a formatted table view object.

    The format of the forexCommentary object has the following format:

    { comment = "Moving nicely"; "created_at" = "2012-12-13T23:30:39+0000"; id = 50ca651f9dc3d1168a04ac96; pair = AUDUSD; rate = "1.0526"; "updated_at" = "2012-12-13T23:30:39+0000"; user = { admin = false; "confirmed_at" = "2012-12-10T21:49:41+0000"; "created_at" = "2012-12-10T21:49:41+0000"; email = ""; "external_accounts" = ( ); id = 50c658f5df52405ff4000c0f; "updated_at" = "2012-12-17T20:46:10+0000"; username = forex; }; }


    function createCommentaryRows(_args) { var tabRows = []; var moment = require('moment'); for (var i in _args) { var tableRow = Ti.UI.createTableViewRow({ height: 70, className: 'CommentaryRow', }); /* it's always a good idea to give you tableview rows a class, especially if the format is common. It helps Titanium to optimize the display */ var layout = Ti.UI.createView({layout:'horizontal'}); var leftPanel = Ti.UI.createView({ layout: 'vertical', width: '30%' }); var pair = Ti.UI.createLabel({ text: _args[i].pair, color: 'black', font: { fontSize: 16 }, }); var rate = Ti.UI.createLabel({ text: _args[i].rate, color: 'black', height: 20, font: { fontSize: 16 }, }); var created = moment(_args[i].created_at); var when = Ti.UI.createLabel({ text: created.fromNow(), color: 'black', height: 20, font: { fontSize: 14 }, }); var comments = Ti.UI.createLabel({ text: _args[i].comment, color: 'black', height: Ti.UI.FILL, width: Ti.UI.FILL, font: { fontSize: 12 }, });text: created.fromNow(), //layout the left panel leftPanel.add(pair); leftPanel.add(rate); leftPanel.add(when); // layout the row layout.add(leftPanel); layout.add(comments); tableRow.add(layout); tabRows.push(tableRow); } latestCommentary.setData(tabRows); };

    The highlighted code will transform the value returned from ACS for the created date, which will have a format that is similar to 2012-12-12T23:16:17+0000 to something far more friendly such as 8 hours ago, or 3 days ago. This is thanks to the functionality in the excellent moment.js library (

  5. Add a call to link it all together. This will call the function to get the commentary and pass the results to the table view formatter function defined in the last step.

    // run this when the form opens forex.getLast3Comments({success: function(e) {createCommentaryRows(e)}});

  6. Run the app!

What just happened?

You created a table view to display the last three currency comments. The content will look as follows:


For the last example, we will show how easy it is to use a different cloud solution. It was said at the start of the article that you can integrate cloud solutions from other providers into your project, and this example will prove it.

This example uses Parse, which was chosen for two reasons. Firstly, and most importantly, Parse has a REST API so we can see an example of cloud integration using REST, and secondly it has an excellent user interface so you see the results at the end of the example.

Time for action – storing custom objects using Parse

We are going to show how you can store a custom object in the cloud via REST API using Parse. We will once again use the forex app for this example. It is a repeat of the last example in that we will be storing the forex commentary again. The only difference is the REST web service used to make the calls. We will store the currency pair, entry price, stop loss, and take profit values.

  1. If you have not already done so, sign up for an account with Parse.

  2. Create a new application. Each application has its own application and API key application ID and API key that are used to authenticate our REST requests. Navigate to the new app then select Overview from the menu bar. The Application ID and REST API key values will be listed on the left. Stay on this screen, we will be using these key values in a couple of steps' time.

  3. Create a new CommonJS-based file in your project root to store our PARSE REST API functionality. In this case call it parseCommentary.js.

  4. Add the following function to the new file. This function will construct the HTML call and then send the request. The highlighted sections show the lines where the application and API keys are specified and also where the custom data object is created:

    function addCommentary(_args) { // create a new currency commentary using Parse var url = ''; var post = Ti.Network.createHTTPClient({ onload : function(e) { console.log("Received text: " + this.responseText); }, // function called when an error occurs, including a timeout onerror : function(e) { Ti.API.warn(JSON.stringify(e)); }, timeout : 5000 // in milliseconds }); // Prepare the connection"POST", url); post.setRequestHeader('X-Parse-Application-Id', '** YOUR APP ID **'); post.setRequestHeader('X-Parse-REST-API-Key', '** YOUR API ID **'); post.setRequestHeader('Content-Type', 'application/json'); var data = JSON.stringify({ pair: _args.pair, rate: _args.rate, comment: _args.commentary }); // Send the request. post.send(data); }; exports.addCommentary = addCommentary;

  5. Return to the forexCommentaryView.js file and change the event listener that listens for the done key on the forex commentary text field. In the previous example this event listener contained the call to the ACS cloud. Make the change highlighted in the following code so that it now calls the parse interface.

    var parse = require('parseCommentary'); commentary.addEventListener('return', function(e) { parse.addCommentary({ pair: thePair, rate: theRate, commentary: e.value}); });

  6. Run the app and enter some commentary!

What just happened?

With one small function you created an interface to a REST-based API. Your code is cloud-enabled in six simple steps! When the app is run and commentary is added you will see an entry on the console, such as that shown in the following command line, indicating a successful transfer:

[INFO] {"pair":"EURJPY","rate":"109.6969","comment":"Drop back on the h4"} [INFO] Received text: {"createdAt":"2012-12-14T07:06:03.833Z","objectId": "l8p1tZSYg5"}

You can also inspect the objects created from the Parse website as shown in the following screenshot:


It is also possible to create the previously mentioned functionality with StackMob. Rather than repeating the examples over again you can look at the Appcelerator blog for an example of how to integrate StackMob into your project at http://developer.appcelerator. com/blog/2011/11/titanium-appcelerator-quickie-stackmob-api-modulepart- one.html.

Other cloud offerings

Suppose the cloud service that you want to use is not in the list shown at the start of this article. Can you use it with Titanium and can you use it for all devices? It's fortunately very easy to work this out.

If the cloud service has either a JavaScript or a REST API, then you can use it with Titanium for cross-platform development. If it only has an iOS or Android SDK (and in that case you would have to question why) then you will need to find a module in the marketplace that will act as an interface or develop your own module.

Choosing your cloud service

This is a rapidly changing area. New players are continually bringing cloud-based solutions to market. Thanks to the success of the cross-platform app development tools such as Titanium, almost all include a JavaScript API, and can therefore be used with Titanium apps. You might think it's simply a matter of choosing the best one for you.

But a word of caution; you need to be aware of the cost of the service. Look beyond the initial developer price. Look at how your app will be funded when it is live. Do the plans you have for your app and the anticipated cost per user match the price you will receive per user from the sale/advertising/other revenue? Do the maths first. Work all this out before you start development. It's too late when your app is live and your platform is costing you more than you are receiving from your app. Imagine how your users would feel when you pulled the Twitter feed and push notifications from your app because you couldn't afford to keep up the hosting prices.

On the other hand, remember the benefits. Please don't let this stop your big idea, just be aware that you will be footing the bill for whatever wonderful service you provide, and that you will be in the same market with other apps that provide wonderful services for free but have considerable resources and a long term view to monetization (or a very bad idea and will bleed cash). If you can't make your wonderful service at a price where your cost received per user is above the cost outlay then you had better change or shelve your idea.

Remember that you are going to be closely linked to your chosen provider. It will be storing lots of important data which will make any changes to the service very hard once the app is live. You need to make the correct decision up front. Also resist the urge to jump on board with a new provider who is offering everything for nothing. Remember they have to fund themselves too. So if they are offering something the others aren't, ask yourself the question, how are they funding it? How will this make them money? You don't want to trust your data to someone who has a high risk business model that results in them going bust in a year's time.


Cloud-based services extend the functionality available on mobile phones, providing extra connectivity features and integration. If you are not using these services yet you probably will be in the next couple of years.

Resources for Article :

Further resources on this subject:

You've been reading an excerpt of:

Appcelerator Titanium Application Development by Example Beginner's Guide

Explore Title