Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

Working With Local and Remote Data Sources

Save for later
  • 9 min read
  • 02 Nov 2015

article-image

In this article by Jason Kneen, the author of the book Appcelerator Titanium Smartphone Application Development Cookbook - Second Edition, we'll cover the following recipes:

  • Reading data from remote XML via HTTPClient
  • Displaying data using a TableView
  • Enhancing your TableViews with custom rows
  • Filtering your TableView with the SearchBar control
  • Speeding up your remote data access with Yahoo! YQL and JSON
  • Creating a SQLite database
  • Saving data locally using a SQLite database
  • Retrieving data from a SQLite database
  • Creating a "pull to refresh" mechanism in iOS

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

As you are a Titanium developer, fully understanding the methods available for you to read, parse, and save data is fundamental to the success of the apps you'll build. Titanium provides you with all the tools you need to make everything from simple XML or JSON calls over HTTP, to the implementation of local relational SQL databases.

In this article, we'll cover not only the fundamental methods of implementing remote data access over HTTP, but also how to store and present that data effectively using TableViews, TableRows, and other customized user interfaces.

Prerequisites

You should have a basic understanding of both the XML and JSON data formats, which are widely used and standardized methods of transporting data across the Web. Additionally, you should understand what Structured Query Language (SQL) is and how to create basic SQL statements such as Create, Select, Delete, and Insert. There is a great beginners' introduction to SQL at http://sqlzoo.net if you need to refer to tutorials on how to run common types of database queries.

Reading data from remote XML via HTTPClient

The ability to consume and display feed data from the Internet, via RSS feeds or alternate APIs, is the cornerstone of many mobile applications. More importantly, many services that you may wish to integrate into your app will probably require you to do this at some point or the other, so it is vital to understand and be able to implement remote data feeds and XML. Our first recipe in this article introduces some new functionality within Titanium to help facilitate this need.

Getting ready

To prepare for this recipe, open Titanium Studio, log in and create a new mobile project. Select Classic and Default Project. Then, enter MyRecipes as the name of the app, and fill in the rest of the details with your own information, as you've done previously.

How to do it...

Now that our project shell is set up, let's get down to business! First, open your app.js file and replace its contents with the following:

// this sets the background color of the master View (when there are no windows/tab groups on it)
Ti.UI.setBackgroundColor('#000');

// create tab group var tabGroup = Ti.UI.createTabGroup();
var tab1 = Ti.UI.createTab({ icon:'cake.png', title:'Recipes', window:win1 });
var tab2 = Ti.UI.createTab({ icon:'heart.png', title:'Favorites', window:win2 });
// // add tabs // tabGroup.addTab(tab1); tabGroup.addTab(tab2);
// open tab group tabGroup.open();

This will get a basic TabGroup in place, but we need two windows, so we create two more JavaScript files called recipes.js and favorites.js. We'll be creating a Window instance in each file to do this we created the window2.js and chartwin.js files.

In recipes.js, insert the following code. Do the same with favorites.js, ensuring that you change the title of the Window to Favorites:

//create an instance of a window
module.exports = (function() {
  var win = Ti.UI.createWindow({
    title : 'Recipes',
backgroundColor : '#fff'
  });
  return win;
})();

Next, go back to app.js, and just after the place where TabGroup is defined, add this code:

var win1 = require("recipes");
var win2 = require("favorites");

Open the recipes.js file. This is the file that'll hold our code for retrieving and displaying recipes from an RSS feed. Type in the following code at the top of your recipes.js file; this code will create an HTTPClient and read in the feed XML from the recipe's website:

  //declare the http client object
var xhr = Ti.Network.createHTTPClient();
function refresh() {
    //this method will process the remote data
    xhr.onload = function() {
        console.log(this.responseText);
    };
    //this method will fire if there's an error in accessing the //remote data
    xhr.onerror = function() {
        //log the error to our Titanium Studio console
        console.log(this.status + ' - ' + this.statusText);
    };
    //open up the recipes xml feed
    xhr.open('GET', 'http://rss.allrecipes.com/daily.aspx?hubID=79');

    //finally, execute the call to the remote feed
    xhr.send();
}
refresh();

Try running the emulator now for either Android or iPhone. You should see two tabs appear on the screen, as shown in the following screenshot. After a few seconds, there should be a stack of XML data printed to your Appcelerator Studio console log.

Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at AU $24.99/month. Cancel anytime

working-local-and-remote-data-sources-img-0

How it works…

If you are already familiar with JavaScript for the Web, this should make a lot of sense to you. Here, we created an HTTPClient using the Ti.Network namespace, and opened a GET connection to the URL of the feed from the recipe's website using an object called xhr.

By implementing the onload event listener, we can capture the XML data that has been retrieved by the xhr object. In the source code, you'll notice that we have used console.log() to echo information to the Titanium Studio screen, which is a great way of debugging and following events in our app. If your connection and GET request were successful, you should see a large XML string output in the Titanium Studio console log. The final part of the recipe is small but very important—calling the xhr object's send() method. This kicks off the GET request; without it, your app would never load any data. It is important to note that you'll not receive any errors or warnings if you forget to implement xhr.send(), so if your app is not receiving any data, this is the first place to check.

If you are having trouble parsing your XML, always check whether it is valid first! Opening the XML feed in your browser will normally provide you with enough information to determine whether your feed is valid or has broken elements.

Displaying data using a TableView

TableViews are one of the most commonly used components in Titanium. Almost all of the native apps on your device utilize tables in some shape or form. They are used to display large lists of data in an effective manner, allowing for scrolling lists that can be customized visually, searched through, or drilled down to expose child views. Titanium makes it easy to implement TableViews in your application, so in this recipe, we'll implement a TableView and use our XML data feed from the previous recipe to populate it with a list of recipes.

How to do it...

Once we have connected our app to a data feed and we're retrieving XML data via the XHR object, we need to be able to manipulate that data and display it in a TableView component. Firstly, we will need to create an array object called data at the top of our refresh function in the recipes.js file; this array will hold all of the information for our TableView in a global context. Then, we need to disseminate the XML, read in the required elements, and populate our data array object, before we finally create a TableView and set the data to be our data array. Replace the refresh function with the following code:

function refresh() {
        var data = []; //empty data array
        //declare the http client object
        var xhr = Ti.Network.createHTTPClient();
        //create the table view
        var tblRecipes = Ti.UI.createTableView();
        win.add(tblRecipes);
        //this method will process the remote data
        xhr.onload = function() {
        var xml = this.responseXML;
         //get the item nodelist from our response xml object
         var items = xml.documentElement.getElementsByTagName("item");
         //loop each item in the xml
          for (var i = 0; i < items.length; i++) {
           //create a table row
           var row = Ti.UI.createTableViewRow({
           title: items.item(i).getElementsByTagName("title").item(0).text
           });
           //add the table row to our data[] object
            data.push(row);
            } //end for loop
            //finally, set the data property of the tableView to 
           our //data[] object
          tblRecipes.data = data;
          };
        //open up the recipes xml feed
        xhr.open('GET', 'http://rss.allrecipes.com/daily.aspx?hubID=79');
        //finally, execute the call to the remote feed
        xhr.send();
    }

The following screenshot shows the TableView with the titles of our recipes from the XML feed:

working-local-and-remote-data-sources-img-1

How it works...

The first thing you'll notice is that we are taking the response data, extracting all the elements that match the name item, and assigning it to items. This gives us an array that we can use to loop through and assign each individual item to the data array object that we created earlier.

From there, we create our TableView by implementing the Ti.UI.createTableView() function. You should notice almost immediately that many of our regular properties are also used by tables, including width, height, and positioning. In this case, we did not specify these values, which means that by default, the TableView will occupy the screen. A TableView has an extra, and important, property—data. The data property accepts an array of data, the values of which can either be used dynamically (as we have done here with the title property) or be assigned to the subcomponent children of a TableRow. As you begin to build more complex applications, you'll be fully understanding just how flexible table-based layouts can be.

Summary

In this article, we covered fundamental methods of implementing remote data access over HTTP. As you are a Titanium developer, we had also understand the available methods to build a successful app. More importantly, many services that you may wish to integrate into your app will probably require you to do this at some point or the other, so it is vital to understand and be able to implement remote data feeds and XML

Resources for Article:


Further resources on this subject: