Building a Twitter Reader With Titanium Mobile.

There are a lot of mobile platforms out there: iOS, Android, Windows Phone, webOS, BlackBerry and Symbian, just to mention a few. Out of all the available platforms, two stick out: iOS and Android. If we look at the US market only, they have a combined market share of 71 percent (comScore, October 2011). This means that if you build your mobile applications for these two platforms, you have covered a lot of end users. The problem is, however, that iOS and Android are two very, very different platforms. Everything from native language support to the application distribution ecosystem is different. To support both platforms you’ll need a team of Java developers for Android and a team of Objective C developers for iOS and virtually nothing they do will benefit both teams.

Luckily, there are options that can help you: Frameworks that aim to bridge the gap between the different mobile platforms. In this entry, we’ll look at Titanium Mobile from Appcellerator. Using the Titanium framework and common technologies like JavaScript, HTML and CSS, you can create applications that are run on both iOS and Android without the need to touch any native code. We’ll create a small application that has become the de facto “Hello, World” application for testing frameworks; a simple Twitter client. Our client will query Twitter for the latest tweets by a given username and display them on the screen.

I’ve never used Titanium before, so this will be a write-blog-entry-as-I-learn-experience. Also, in spite of being a software professional for almost ten years now, I’ve got very little experience with JavaScript. The reason for this is that when I first started to look at JavaScript many years ago it was a immense mess of spaghetti code that had to be tailored for every single browser and the experience gave me headaches and high blood pressure. So, for me, learning to use Titanium will be a real double rainbow because it’ll allow me to play around with not just one, but two new toys.

Everything in this entry assumes that you have you’ve already got Titanium Studio and all of it’s prerequisites installed, configured and up and running. Another assumption is that you have an Android device available that you can use to test our application. To be honest, getting Titanium ready was a major pain because there are a lot of applications that have to be installed. If you are, like me, developing on Windows 7, you can use this somewhat outdated guide written by Appcelerator themselves for installation instructions. Note that you will not be able to create an iOS version of our application when you are developing on Windows. Unfortunate, but it’s the harsh reality when working with Apple technologies. Why, then, even bother using Windows when developing using the Titanium framework? Good question. Since the source code we’ll write is platform agnostic – it’s JavaScript, not native code – it should, at least in theory, be possible to import our Twitter client project in Titanium Studio on a Mac and create an iOS version there. This enables each developer to use their preferred work environment to create applications. In my case, that is Windows 7. But it would have been Ubuntu if my employer’s VPN login supported more browsers than IE. Honestly.

Anyway. Let’s get started, already!

If you’re having problems with any of the code below, you can download the complete Titanium Studio project here.

  1. In Titanium Studio, press Alt+Shift+N and select “Titanium Mobile Project” from the popup menu. Name the project “Twitter Reader” (without the quotes), enter “com.test.twitterreader” as App Id and click the Finish button. Titanium Studio creates a skeleton project that will be the basis for our Twitter client.

  2. Now would be a good time to connect your Android device to your computer. Make sure it is configured for application debugging (settings->Applications->Development->check USB debugging) and that you have proper USB drivers for your device installed.

  3. In the App Explorer on the left hand of the screen you’ll see a “Play”-button (upper left). Click on the arrow to the right of the button and select “Android Device”. The Titanium Studio will now compile and install our skeleton application on the device. When it’s ready, you’ll find the application “Twitter Reader” together with the rest of your applications on the connected device. Open it and marvel at your first Titanium application, created in a matter of minutes (not counting the hours you used to install Titanium).

  4. The next step is to replace everything in the app.js file with the following code. This will strip the skeleton further, and the only thing being displayed if you install and start the application again will be a black main window with the title “Twitter Reader”.

    1
    2
    3
    4
    5
    
    Titanium.UI.setBackgroundColor('#000');
    var twitterWindow = Titanium.UI.createWindow({  
        title:'Twitter Reader',
        backgroundColor:'#fff'
    });

  5. Titanium has a lot of built in libraries we can utilize to quickly do a lot of things that might have been a bit of a hassle if we were coding in Java or Objective C. One of those libraries provide an HTTP client that we will use to query Twitter for the most recent tweets by a given username. Add the following to app.js:

    7
    8
    9
    10
    11
    
    var twitterUserName = "vegardskjefstad";
    var httpClient = Ti.Network.createHTTPClient();
    httpClient.timeout = 10000;
    httpClient.open("GET","http://api.twitter.com/1/statuses/" + 
    	"user_timeline.json?count=10&screen_name=" + twitterUserName);

    This will create an HTTP client that connects to Twitter and asks for the user timeline of my Twitter account in JSON format. If you want to use another Twitter account, simply change the value of the twitterUserName variable. on line 7.

  6. Next we have to do something with the response from the Twitter server. First, we create an array, twitterData, where we’ll store a selection of the data in the response. Then we tell the HTTP client we use what to do when it receives a successful response from the Twitter server:

    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    
    var twitterData = [];
    httpClient.onload = function() {
    	try {
    		var tweets = JSON.parse(this.responseText);
    		for (var i=0; i < tweets.length; i++) {
     
    		}
    	} catch(E) {
    		alert(E);
    	}
    };

    This block of code will serve as the basis for our processing of the data from Twitter. It splits the response into pieces that can be handled by the code and then loops through all the data. It doesn’t do anything with the data yet, but that will change soon as we start to add code in the body of the for-loop on line 17.

  7. First, we add code that extract the tweet text, username, avatar URL and tweet date from the response. We also create a table view row where we’ll eventually display the data for a particular tweet:

    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    		...
    		for (var i=0; i < tweets.length; i++) {
     
    			var tweetText = tweets[i].text;
    			var user = tweets[i].user.screen_name;
    			var avatar = tweets[i].user.profile_image_url;
    			var created_at = tweets[i].created_at;
     
    			var row = Ti.UI.createTableViewRow({hasChild:true,
    				height:'auto'});

  8. Next we take the data we just extracted and insert them into visual elements defined by Titanium like views, image views and labels. This is quite a lot of code, but I suspect still not as much as if you’d done this in either Java or Objective C.

    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    
    			...
    			var postView = Ti.UI.createView({
    				height:'auto',
    				layout:'vertical',
    				left:5,
    				top:5,
    				bottom:5,
    				right:5
    			});
     
    			var avatarImageView = Ti.UI.createImageView({
    				image:avatar,
    				left:0,
    				top:0,
    				height:48,
    				width:48
    			});
     
    			postView.add(avatarImageView);
     
    			var userLabel = Ti.UI.createLabel({
    				text:user,
    				left:54,
    				width:120,
    				top:-48,
    				bottom:2,
    				height:16,
    				textAlign:'left',
    				color:'#444444',
    				font:{fontFamily:'Trebuchet MS',fontSize:14,
    					fontWeight:'bold'}
    			});
     
    			postView.add(userLabel);
     
    			var dateLabel = Ti.UI.createLabel({
    				text:created_at,
    				right:0,
    				top:-18,
    				bottom:2,
    				height:14,
    				textAlign:'right',
    				width:110,
    				color:'#444444',
    				font:{fontFamily:'Trebuchet MS',fontSize:12}
    			});
     
    			postView.add(dateLabel);
     
    			var tweetTextLabel = Ti.UI.createLabel({
    				text:tweetText,
    				left:54,
    				top:0,
    				bottom:2,
    				height:'auto',
    				width:236,
    				textAlign:'left',
    				font:{fontSize:14}
    			});
     
    			postView.add(tweetTextLabel);
    			row.add(postView);
    			twitterData[i] = row;
    		}

  9. The last thing we’ll do inside the body of the try-block (but outside the body of the for-loop) is to add a table view with all the Twitter data we’ve processed to the main window of our application.

    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    
    			...
    		}
     
    		var tableview = Titanium.UI.createTableView({data:twitterData,
    			minRowHeight:58});
    		twitterWindow.add(tableview);
    		twitterWindow.open();
    	} catch(E) {
    		alert(E);
    	}
    };

  10. All the code that process the data is of no use if we don’t get any data from the Twitter server. There’s only one thing left to do to get our Twitter client operational and that’s to request data from Twitter:

    99
    
    httpClient.send();

  11. Now once more tell Titanium Studio to install Twitter Reader on your connected device and open it when it’s installed. A window should open and you should shortly see the 10 latest tweets by me.

So, there you have it: A Twitter client in less than 100 lines of code. Pretty amazing. Since I don’t have the iOS simulator or an actual iOS device available for testing, I can only confirm that the client is working on Android. We’ll just have to trust Appcelerator in their claim that everything will work on iOS as well.

This should be enough for proof for everyone that Titanium Mobile is great and that we should never ever again have to code anything using a native language. Or maybe not. Before you go nuts and throw away all your Java and Objective C books, there are a few things you should consider.

Firstly, frameworks like Titanium are nice, but you lose control of the native code. You can never be sure if the framework converts its code to the most efficient version of the native code. Secondly, frameworks will always lag behind the release versions of the native platforms they support in terms of available features. Thirdly, you will soon find yourself in situations where you have to customize parts of the code for specific mobile platforms. Frameworks are not he holy grail of mobile applications, but they can be very helpful in certain cases. Titanium Mobile is certainly worth considering if you are going to make an application that has to work on both iOS and Android.

Sources:
Titanium Mobile: Installing on Windows 7
Appcelerator Documentation Center – Documentation
Getting Started with Kitchen Sink.
appcelerator/KitchenSink – GitHub

  • Kristian J.

    Nice article, but eval() for parsing json? Tsk, tsk..

    • http://twitter.com/vegardskjefstad Vegard Skjefstad

      eval() is a result of my lack of experience with JavaScript and that they were doing JSON parsing like this in the Titanium Mobile tutorials. What would be the preferred way of doing JSON parsing in JavaScript?

  • http://twitter.com/haavardt Håvard Tegelsrud

    I would recommend changing line 17 in step 7,  ”var tweets = eval(‘(‘ + this.responseText + ‘)’);” with this line: 
    “var tweets = JSON.parse(this.responseText);”. Because eval is evil.

    • http://twitter.com/vegardskjefstad Vegard Skjefstad

      I’ll try that and report back. Thanks!

  • http://twitter.com/vegardskjefstad Vegard Skjefstad

    I’ve tested using JSON.parse(…) and that works like a charm and I’ve updated the example code accordingly. Thanks a lot!