Get $500+ of the best After Effects files, video templates and music for only $20!
Appcelerator: Using JSON to Build a Twitter Client

Appcelerator: Using JSON to Build a Twitter Client

Tutorial Details
  • Technology: Appcelerator
  • Difficulty: Beginner
  • Completion Time: 60 Minutes

The Twitter API provides a wealth of resources to extend the functionality of mobile applications. When working with this API, results can be provided in either the XML or JSON data format, and this tutorial will be using the lightweight JSON format to create a Twitter iPhone application that will read the latest tweets by Mobiletuts+. We will see how the Appcelerator SDK makes the development of our application a piece of cake!

Step 1: Create the Twitter App Project

Fire up Titanium Developer and create a new project. Select “Mobile” from the drop-down for the Project Type.

Give your application a Name and an App ID, choose a directory to save your project within, and pass in a URL in the Company/Personal URL field.

Finally, select the latest Titanium SDK and click “create project.”

Appcelerator: Create a New Project

NOTE:
This tutorial is created with the Titanium SDK version 1.3.0 and will work perfectly with the SDK versions 1.3.0 and below. The Titanium SDK version 1.4.0 is up for release and is available for download here. This application may not work with SDK 1.4.0 as the SDK is still undergoing beta testing.

Step 2: Create a Tab Group

Titanium Developer provides us with the following default application when we create our project:

Appcelerator: Default Application Screen

The default application consists of two tabs at the bottom of the screen, and a navigation bar on the top. The white area in the middle is referred to as a window. Each tab is held by a tab group, and, further up the view hierarchy, each tab is associated with its own window to be displayed when the tab is selected. The labels in the window are considered “children” of the window.

The project consists of multiple files by default. The file “app.js” (located in the Resources folder) is the backbone of our application. All the coding is done in this file and other files linked to this file.

Appcelerator: The Resources Folder

So, let’s begin by opening app.js. Delete the default code, and create our tab group by entering the following:

// Creates a tab group with Titanium.UI API. var tabGroup =
Titanium.UI.createTabGroup();

tabGroup.open();

The above code creates a tab group named “tabGroup” that will hold out tabs. The “open()” method will open our tab group after the application loads.

Note:
All user interface elements in Appcelerator are variables.

Step 3: Create the Twitter Tab

We will now create the tab which will hold our Twitter window and content. The tab will be a child of the tab group we created in step 2.

The method for creating a tab requires three arguments: “title,” “icon,” and “window.” The arguments are passed inside of a pair of curly braces.

Let’s go over what each argument does:

  • title: This argument takes a string as a name for our tab.
  • icon: The “icon” argument shows the image on the tab. The image name is passed in as a string.
  • window: This argument is perhaps the most important of all. This argument links the tab to its corresponding window.

Apply the above with the following code:

// Create the tab "mainTab"
var mainTab = Titanium.UI.createTab({
    title: "Twitter", // Title of the tab: "Twitter"
    icon: "KS_nav_mashup.png", // Icon for tab : Included in the source files
    window: mainWin  // We will create the window "mainWin"
});

// Add the tab to our tab group
tabGroup.addTab(mainTab);

Lines 2- 6 create the main tab for our application, and line 9 adds that tab to our tabGroup to be displayed on the screen.

Step 4: Create the Twitter Window

Let’s continue by creating our window.

A “window” can be thought of as a UI element that is able to hold other UI elements. Another UI element that is able to do this is called a “view,” but one of the main differences between views and windows is that views are able to embed additional views within themselves, whereas windows are unable to embed other windows, but are able to embed views.

The method to create a window is similar to those used to create our tab group and tab. The arguments are:

  • title: This argument shows the title of the window in the navigation bar at the top of the screen. The name is passed in as a string.
  • backgroundColor: This argument gives our window a backgroundColor. If you don’t pass in this argument, the window remains transparent.
  • url: This argument provides link to the file which will contain the code for our window. The path is passed in as a string

Type the following to create the main window:

// Create the window "mainWin"
var mainWin = Titanium.UI.createWindow ({
    title: "@mobtuts", // Set the title
    backgroundColor: "#fff", // Set the background color to white
    url: "tweets.js" // Link to file which will handle the code for the window
});

Your code should now look something like this in app.js:

// Creates a tab group with Titanium.UI API.
var tabGroup = Titanium.UI.createTabGroup();

// Create the window "mainWin"
var mainWin = Titanium.UI.createWindow ({
    title: "@mobtuts", // Set the title
    backgroundColor: "#fff", // Set the background color to white
    url: "tweets.js" // Link to file which will handle the code for the window
});

// Create the tab "mainTab"
var mainTab = Titanium.UI.createTab ({
    title: "Twitter", // Title of the tab: "Twitter"
    icon: "KS_nav_mashup.png", // Icon for tab, Included in the source files
    window: mainWin // We will create the window "mainWin"
});

// Add the tab to our tab group
tabGroup.addTab(mainTab);
tabGroup.open(); 

Don’t forget to create the “tweets.js” file in the Resources folder or you will get an error when you launch the application. You can leave it empty for now.

Launch the project from Titanium Developer. If you have followed correctly, you should see something like this in the iPhone Simulator:

Appcelerator: First Time Project Launch Screen

Step 5: Setup the tweets.js Shell

Now we are done with coding in “app.js.” The rest of the tutorial will cover the code needed for “tweets.js.” Go ahead and open it now.

We need a variable to hold the current window. This is done by the following method:

// Create variable "win" to refer to current window
var win = Titanium.UI.currentWindow;

Now we can communicate with the window which we are currently in through the variable “win.” To keep our code semantic, we would like to make a function that is responsible for getting our tweets, and displaying them in our application. Let’s create a function called loadTweets():

// Function loadTweets()
function loadTweets() {

}

Let’s continue by creating an empty array that will hold the data for our table view which we will create later on in this tutorial. The data for each row is passed inside of a pair of curly braces:

function loadTweets() {
    // Empty array "rowData" for our tableview
    var rowData = [];
}

Step 6: Working With the Twitter API

The Twitter API provides us with many methods to get tweets from Twitter. You may want to head over to the official Twitter API documentaiton for further details. The method that we are interested in is statuses / user_timeline.

A typical response from Twitter to the request we are going to make looks something like this in JSON:

{
    "in_reply_to_screen_name": null,
    "created_at": "Thu Mar 18 14:57:04 +0000 2010",
    "favorited": false,
    "place": null,
    "coordinates": null,
    "source": "Crying Indian",
    "contributors": null,
    "in_reply_to_user_id": null,
    "truncated": false,
    "geo": null,
    "in_reply_to_status_id": null,
    "user": {
        "statuses_count": 17,
        "created_at": "Wed Mar 03 19:37:35 +0000 2010",
        "description": "",
        "favourites_count": 0,
        "profile_sidebar_fill_color": "DDEEF6",
        "screen_name": "oauth_dancer",
        "contributors_enabled": false,
        "following": true,
        "geo_enabled": false,
        "time_zone": null,
        "profile_sidebar_border_color": "C0DEED",
        "url": "http://bit.ly/oauth-dancer",
        "verified": false,
        "location": "San Francisco, CA",
        "profile_text_color": "333333",
        "notifications": false,
        "profile_background_image_url": "http://a3.twimg.com/profile_background_images/80151733/oauth-dance.png",
        "protected": false,
        "profile_link_color": "0084B4",
        "followers_count": 9,
        "name": "OAuth Dancer",
        "profile_background_tile": true,
        "id": 119476949,
        "lang": "en",
        "utc_offset": null,
        "friends_count": 11,
        "profile_background_color": "C0DEED",
        "profile_image_url": "http://a3.twimg.com/profile_images/730275945/oauth-dancer_normal.jpg"
    },
    "id": 10674682220,
}

As you might notice, the keys that we are looking for are “screen_name,” “text,” and “profile_image_url.” Both “screen_name” and “profile_image_url” are located under the “user” key.

We need to make an HTTP request in order to get the data from Twitter. The method type for our HTTP request is going to be “GET” and the url will be:


http://api.twitter.com/1/statuses/user_timeline.json?screen_name=mobtuts

We ask the Twitter API for the user timeline and the type of format we would like to receive our response in. Finally, we provide the screen name of the user we would like to get our tweets from.

Step 7: Communicate with the Twitter API

We are going to use the createHTTPClient() method provided by the Titanium API to make our HTTP request to Twitter API. You might want to head over to Titanium documentation for more information on the HTTP Client over here. Let’s implement this in our code:

function loadTweets() {
    // Empty array "rowData" for our tableview
    var rowData = [];

    // Create our HTTP Client and name it "loader"
    var loader = Titanium.Network.createHTTPClient();
}

We need to run three methods for our HTTP client. Let’s implement the three methods in our code:

// Sets the HTTP request method, and the URL to get data from
loader.open("GET","http://api.twitter.com/1/statuses/user_timeline.json?screen_name=mobtuts");

// Runs the function when the data is ready for us to process
loader.onload = function() { // TODO: Implement what to do after the data is received };

// Send the HTTP request
loader.send();

The “open()” methods requires two arguments separated by a comma. The first argument is the method of the HTTP Request, which in our case is going to be the “GET” value.

The second argument is the URL of the API which we will get our data from. The “onload()” method is run when the data is received and is ready for us to work on. This is where we parse the JSON we receive, and display it in a table view. We will work on it in the next step.

The “send()” method sends the HTTP request. One advantage of this method is that it shows an activity indicator in the status bar by itself rather than us coding for it.

Step 8: Parsing the Twitter JSON

Now that we have our HTTP client, let’s parse the JSON that we receive.

First, we evaluate the JSON which we receive through the “eval()” function. We pass in the JSON as a string. Javascript does the rest of work for us. We store the parsed JSON in a variable called “tweets.”

loader.onload = function () {
    // Evaluate the JSON
    var tweets = eval('('+this.responseText+')');
}

Now that we have our parsed JSON in the variable, we would like to run through all the keys inside the variable and get the keys “user,” “text,” and “profile_image_url” for each tweet. We will create a for loop to do so:

var tweets = eval('('+this.responseText+')'); 

for (var i = 0; i < tweets.length; i++) {
    var tweet  = tweets[i].text; // The tweet message
    var user   = tweets[i].user.screen_name; // The screen name of the user
    var avatar = tweets[i].user.profile_image_url; // The profile image
}

Now that we have the tweet, the user, and the avatar, let’s make a view that will hold the information.

We will call this view “post_view.” We would like our post_view to show the avatar on the left, the user’s name on the side, and the tweet below the screen name. Then we will add our post_view to a row. We would like our row to look something like this:

Appcelerator: A Single Row

Let’s implement this in our code:

// Create a row and set its height to auto
var row = Titanium.UI.createTableViewRow({height:'auto'});

// Create the view that will contain the text and avatar
var post_view = Titanium.UI.createView({ height:'auto', layout:'vertical', top:5, right:5, bottom:5, left:5 });

First we create our post_view and row. We set our row’s height to auto so that it can expand or contract as needed. We also set our view’s height to auto and layout to vertical. The view positions itself 5 pixels away from all the four sides of its parent.

Step 9: Displaying our Data

Now that we have our post view and row ready for us to work on, let’s create an image view that will hold our profile image. The image view will have both height and width set to 48 pixels. Then we add our image view to the post view, as shown below:


// Create image view to hold profile pic
var av_image = Titanium.UI.createImageView({
    url:avatar, // the image for the image view
    top:0,
    left:0,
    height:48,
    width:48
});

post_view.add(av_image);

Next, create a label that will show the username for our post view:

// Create the label to hold the screen name
var user_lbl = Titanium.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'
    }
});

post_view.add(user_lbl);

We format the label to have text grey in color, and also we align it to the left side. We set the text property for our label to variable user. We then add the label to the post view.

Now let’s create our final element for the post view. We will create a label that will contain the tweet message and format it to position properly in the post view:

// Create the label to hold the tweet message
var tweet_lbl = Titanium.UI.createLabel({
    text: tweet,
    left: 54,
    top: 0,
    bottom: 2,
    height: 'auto',
    width: 236,
    textAlign: 'left',
    font:{ fontSize:14 }
});

post_view.add(tweet_lbl); 

Last but not the least, we add our complete post view to our row. Also, we give each row a class name because we might want to refer to them in future. We add our row to the “rowData” array every time the for loop is run. This is the final code for our for loop:

// Add the post view to the row
row.add(post_view);

// Give each row a class name
row.className = "item" + i;

// Add row to the rowData array
rowData[i] = row;

Step 10: Finishing up!

Let’s continue by creating a table view that will show the rows that we have stored in the “rowData” array. We then add the table view to the window. The following code goes outside the for loop but inside the “loader.onload” function:

// Create the table view and set its data source to "rowData" array
var tableView = Titanium.UI.createTableView( { data : rowData } );

//Add the table view to the window
win.add(tableView);

Now we must run the loadTweets() function at the end of our “tweets.js” file:

loadTweets();

Your finished application should look something like this:

Appcelerator: Twitter Application Final Preview

Conclusion

In this tutorial, we went over creating table views, tabs, and getting remote data. We also learned how to parse JSON and use it in our application.

You may go to these additional resources to expand your knowledge of the Appcelerator SDK and Titanium APIs:

Add Comment

Discussion 36 Comments

  1. Ben says:

    meh :< I'd like to see App-Building with Titanium for Android.

  2. Great tutorial! Can’t wait to start! :)

  3. Andrew says:

    Great article. Will be testing it out shortly.

  4. Carlos says:

    Axit,
    Question. How do you get the data to constantly update. I see you put the call function. But looks like it fires once. I would put a double tap eventListener on the window or a button to update the data. I have tried a setInterval, but since Android, maybe the new iPhone pauses the application when you go do another task, the setInterval does not work. You either have to manually fire another call or close the app completely and restart it. I know that is the way iPhone and iPod OS 3.1 work. Not sure about the 4.0 version.

    I have developed an app on Android because I own one.

    This app can be built for Android. Titanium is cross platform software, the only difference is that the interface will match the Android OS.

    Let me know what you would like to do and I may be able to try to write a tutorial for it. Something not too hard though. Something like this twitter feed thing would be easy enough. I could just extend Axit’s tutorial for Android if need be.

    Thanks, good tut.

    • Axit Patel says:

      Hey Carlos,

      Its actually a really good question. Well I couldn't find a definite way to constantly update the tweets, but you can do so manually. I was going to show the manual way to do it but due short notice I couldn't do so. If I were to do something like that, I would add a refresh button on the top of the navigation bar. Here is the code you would add in tweet.js for the refresh button:

      var refreshBtn = Titanium.UI.createButton({

      systemButton: Ti.UI.iPhone.SystemButton.REFRESH

      });

      refreshBtn.addEventListener('click', function() {

      loadTweets();

      });

      win.add(refreshBtn);

      Hope that helps! Let me know if you could find a way to automate it. Glad you asked :)

      • Axit Patel says:

        Sorry I made a slight mistake. Instead of:

        win.add(refreshBtn);

        you would like to change it to:

        win.setRightNavButton(refreshBtn);

        Appologies for the mistake.

      • carlos says:

        Axit, that solution is the way I would do it too. Or a double tap on the screen. Either way works.

        Is setRightNavButton in your next response in the Titanium API. I checked their site and it doesn’t look like it. Is this for iPhone only?

        The auto update thing might be possible if the application was left open. Or try to figure out a way to detect if the window was opened or the application had started up again. Not quite sure how to do that yet. I have seen it done on other apps when you reenter the page or hit the tab the page refreshes, but don’t quite know that one yet.

    • Ben says:

      Some Tutorials or rather an Android version of this tutorial would be awesome! :)

      Another general question: Is there an Titanium Android Development Sheet which contains all the objects etc. which I can use for Android development?

      • Carlos says:

        Ben,

        I would have to get permission from Axit to redo his tutorial for the Android. However, it is actually pretty much the same exact thing. The Ti.UI.iPhone specific stuff you would mainly just leave out.

        When Titanium compiles the code, if you have the Android ADK installed, Appcelerator Titanium will compile a version for Android (and iPhone if developing on a Mac with the developers kit).

        No changes in code are really needed. Android will just use it's own interface.

        On Appcelerator's developer center page at developer.appcelerator.com/apidoc/mobile/1.3 will give you API references for Appcelerator.

        They still do need to get better documentation and code examples, but here at MobileTuts I think is your best bet for an "Appcelerator Community". Appcelerator's Q&A pages are pretty good at answering most question. The Appcelerator guys are pretty good an answering the Q&A pages too.

        They have posted a few things on their Developer Blog as code examples, but not too much and most of it is pretty advance stuff not really beginner stuff.

        Just be sure to stay up on their SDK versions. They seem to move pretty fast on updating and releasing new versions.

      • Ben says:

        Okay , thanks! :)

  5. David Gyori says:

    Nice tutorial!
    Maybe a dummy question: is it legal to develop iOS4 apps with Appceleratior? Will Appstore accept my application?

    • Axit Patel says:

      Hey david,
      Although it is possible to develop iOS4 apps with Appcelerator, I’d rather wait for the release of Titanium Mobile SDk 4.0 which has better iOS4 support. Hope that helps :)

  6. Luis says:

    Nice tutorial, I just have one problem.

    I got it to work with Android, however the Layout is all messed up.

    I removed the layout:'vertical' and set up the top and left properties myself, it starts cropping the text.

    Is there any way to make the layout work correctly with Android?

  7. dan tamas says:

    Why are you creating a unique className for each row?

    The rows are identical. You can leave one className only.

    It will improve the performance of the rendering.

    Also you used eval( this.responseText).

    You can use

    JSON.parse( this.responseText)

  8. Karthik Jayapal says:

    I tried this example for building an android app. While the functionality works as expected, the interface is not exactly same. It needs lots of UI fixes. How do we build an app that looks same in both iPhone and Android.?

  9. anticafe says:

    Thanks for useful article.
    But how about post a tweet using Titanium?

  10. Steve says:

    Fantastic tut. Does any know how you would make the links in tweets actually be links? Would you have to a create a web view for each row?

  11. PaulB says:

    I did a few tweaks to improve this example on Android. The twitter handle was below the image and many tweets got truncated.

    Details of the changes are at https://docs.google.com/document/edit?id=1fI05XkQFNDHIlQtJo5jcCgOPndV4lizWxUS1885J2yw&hl=en&authkey=CNzZp6cB and the updated tweets.js is at https://docs.google.com/document/edit?id=1MZl2bFc_Js_xIO0hLodSFaXMfrs7830m8tyg4auyJ3s&hl=en&authkey=CMftl7UN#

  12. Clifford says:

    Hi Axit,

    Great tutorial! I ran it on my android phone and it worked!

    I later added a keyword argument to the function to turn it into a search….like this…

    function loadTweets(keyword) {
    var rowData = [];
    var loader = Titanium.Network.createHTTPClient();
    loader.open(“GET”,”http://search.twitter.com/search.json?q=”+keyword);
    …..
    …..

    I fired loadTweets(“appcelerator”) and it worked fine. When I search a second time, the search results displayed in the tableview object were stacked on top of the first set of results, causing the text and images to overlap. How do I ‘flush’ the tableview before displaying the second set of results? ^_^

    • Conor says:

      If you want to flush your tableView to become an empty table use the following:
      tableView.setData({});

      However your problem is arising because the tableView creation is contained within the loader.onload() function which is inside the loadTweets() function. Each time you call it you’ll make a new tableView hence the overlap. In reality we only want to use one and change its data per search instead.

      As its been a while since your last post I’ll assume you’ve found a fix yourself so here’s how to do it for everyone else:

      Move the tableView’s declaration to outside of the loadTweets function and place it at the bottom of the file.

      In tweets.js

      So first remove the cut out the old creation (look for this code)


      // Create the table view and set its data source to “rowData” array
      var tableView = Titanium.UI.createTableView({data:rowData});
      //Add the table view to the window
      win.add(tableView);

      You can replace that code with this

      // Set set the table data
      tableView.setData(rowData);

      Place the table declaration at the bottom of the file but just above our loadTweets();
      Oh and we won’t use any constructor setting code so get rid of that too.

      // Create the table view
      var tableView = Titanium.UI.createTableView(); // Notice no rowData
      //Add the table view to the window
      win.add(tableView);

      loadTweets();

      You can call loadTweets() until your hearts content and it will show fresh data each time.

      I know I could have just posted up the amended source code but wheres the fun in that.
      Hope this works for everyone.

  13. Maxwell Barvian says:

    Great tutorial! I’m only afraid it will inspire even more Twitter clients :p

  14. Greg says:

    This is great.

    I’m trying to build something similar. I have a rails app and it’s outputting JSON, but the JSON.parse( this.responseText) and eval(‘(‘+this.responseText+’)'); aren’t working for my app but they work for twitter.

    When you output json in rails, do you have to do anything special for appcelerator?

  15. nccwarp9 says:

    How can user name or tweet text be extracted from tableview and shown.. lets say in a alert box ?

  16. Carsoz says:

    Thank you for the twitter tutorial. I have also found a good beginner tutorial for Appcelerator Titanium here: http://appceleratortitanium.com/tutorials/3-appcelerator-titanium-tutorial-beginners.html

  17. Omprakash says:

    Hi,

    Nice tutorial, I need to post comment on twitter using titanium. Please provide me a sample.

    thanks,
    Om

  18. travis says:

    I copied the tweets.js from PaulB (Droid 2 here) and it is giving me a blank screen with the Twitter button still at the top. Anyone else come into this problem?

  19. tollaNene says:

    Hello all! I like this forum, i set up many gripping people on this forum.!!!

    Great Community, good all!

  20. ashish says:

    Nice tutorial.
    I tested out, it worked !

    Thanks

  21. Priyanka says:

    great tutorial series. Right point to start the titanium development

  22. giongic says:

    Hello, I tried to run this app in my Titanium environment. All I get is a minimal layout with an entry:

    Please follow @envatomobile.

    Can you please tell me the reason? Thanks.

  23. Andy Macintosh says:

    Hey, It’s not outdated. Just update the twitter API url to get tweets from some other user.

  24. Ravi says:

    i m confuse about which parsing is use json class provided by android or gson API.which one is good?

    can anybody tell me answer of the following problem?
    suppose on the client i want to access web service and consider that web service return java object instead of json string then is it possible to parse that java object into json object and shows the result in android listview????????. if no then tell me the solution of this problem.Thanks in advanced….

  25. Eric says:

    Weird, how come I am getting only 1 tweet and not many tweets? I copy paste the same code from the source files too, same results. I tried different tweet’s accounts but also same issue.

    Any help on this? Thanks.

Add a Comment

To add a code snippet to your comment, please wrap your code like so: <pre name="code" class="html">YOUR CODE</pre>. You can replace the class name with "js," "css," "sql," or "php." If there are any "<" or ">" within your code, please search and replace them with: &lt; and &gt; respectively.