PhoneGap: Build a Feed Reader - Project Structure
Although not specifically created to work together, jQuery Mobile and Cordova (also known as PhoneGap) are a very powerful duo to create hybrid, mobile apps. This series will teach you how to develop a feed reader using web technologies and these two frameworks. Over the course of this series, you'll also become familiar with the Cordova Connection and Storage Core Plugins and the Google Feed API.
The app we'll build in this tutorial, called "Audero Feed Reader", is very small and easy to understand. It's a basic Feed reader that will help you to keep all the news and the articles you care about in one place. After all, Google shut down Google Reader, so we have to replace it, don't we?
On the Home screen of the app, we'll place two buttons to highlight the two main features: an add a new feed button and a list of saved feeds. The layout of the Home screen is shown with the following screenshot:
To keep the project as simple as possible, we'll only be saving the name of the feed and its URL. So, once the user clicks the "Add Feed" button, we'll display a form with just two input boxes as shown by the image below:
Now that the user is able to save as many feeds as wanted, it's time to allow him to view the list of those feeds saved. In addition, to help the user easily find a feed, the list is ordered alphabetically by name and it has also a search box, in case the feeds are too numerous. You can see an example of the described page looking at the screenshot below:
Once the user chooses a feed, the app fetches the URL and shows the entries available. To easily parse the different types of feeds (Atom, RSS, or Media RSS), we'll take advantage of the Google Feed API, and specifically the Google Feed JSON interface. The latter will parse the requested URL for us and return a unified and easy-to-parse JSON object. We'll discover more on this API in the next part of this series. By default, to save on bandwidth, Audero Feed Reader will only require 10 entries. To allow the user to retrieve more data, we'll add a "Show more" button. Of course, the data will be actually retrieved only if the provided Feed exposes more than 10 entries. For example, Mobiletuts+ provides only 10 entries, so if the user clicks the "Show more" button, the message "No more entries to load" will be prompted.
To save space, the entries are organized with an accordion and, by default, only the title is visible. However, the user can see more details if needed. The app also displays the entry's summary, the author, and a button reading "Go to the Article" to read the full article on the relative website. Note that to enhance the usability, we'll also show again the title, but this time it can be clicked to access the full article.
The final look and feel of this page is shown below:
At this point we know what to do, so it's time to see how we'll do it. The technologies involved in the development of Audero Feed Reader are:
- HTML 5: To create and markup the pages.
- CSS 3: To style the pages. Note that we won't have a custom CSS stylesheet and we'll only use the one provided and required by jQuery Mobile.
- jQuery: jQuery will be used to select elements, attach event handlers, and run AJAX requests. It is also a dependency of jQuery Mobile.
- jQuery Mobile: This is our framework of choice to create the UI of our pages. It allows us to easily optimize a website for mobile devices and quickly create mobile interfaces. At the time of writing, the most recent version available and used is 1.3.1.
- PhoneGap: Wraps all our files so we can compile them as if we were building a native app. Morever, PhoneGap offers some interesting and useful APIs to communicate with the device hardware, such as Storage and Connection. The version used is 3.0, a recent and significant improvement over 2.x.
In addition to the above, we'll use also these specific Cordova Core Plugins:
- InAppBrowser: This is
a web browser that displays in the app when calling. Since version 2.3.0, two important methods have been added:
InAppBrowserwindow. We won't use these methods in our app but I wanted to mention them. To learn more, visit the InAppBrowser official doc.
- Storage plugin: Provides access to the device's storage options. Note that, as the documentation asserts, some devices already provide an implementation of these specifications, in which case the built-in support applies. Cordova's implementation offers compatible support for those that don't. To read more, take a look at the Local Storage doc.
- Notification plugin: Lets you create visual, audible, and tactile device notifications. Of the several methods available, we'll use just
alert()to show some messages to the user. For example, this plugin will be used when a user successfully adds or deletes a feed. For more information, refer to the Notification docs.
- Connection plugin: It's made of just one property that provides information about the device's connection status (e.g. WI-FI, 3G, none, etc.). Please note that since version 2.3.0, you should access the
Connectionobject using the new
navigator.connectionproperty. This property matches the W3C specification, instead of the previous
navigator.network.connectionproperty. More on this here.
If you used previous versions of PhoneGap, you'll recognize that these plugins are nothing but what you used to know as APIs. The name change is due to the new PhoneGap architecture. Don't worry though, apart from the name, almost everything is the same. If you want to learn about all the latest and greatest improvements with 3.0, you can read the introductory article and the Getting Started guide.
1. Install PhoneGap
Starting from version 3.0.0, the development team introduced a new procedure to install PhoneGap that requires Node.js and npm. In addition, no simple download links are provided as a fallback at the moment. Therefore, the rest of the tutorial assumes you have both of these software packages installed and working. Once done, the first step is to type the following command to install PhoneGap:
npm install -g phonegap
If you're using Linux, remember to prepend
sudo to the previous line.
2. Initialize the Project
Before creating the project folder, it's worth noting that the development team also introduced a command line in this new release to help developers performing common tasks like building and running the app or installing plugins. The CLI also allows you to initialize a project. Not only will create a folder with the PhoneGap library inside, but it will also generate an application's skeleton. To initialize the project, you simply type the following command:
phonegap create audero-feed-reader com.audero.free.utility.auderofeedreader "Audero Feed Reader"
The first argument specifies the name of the directory to create. The other two arguments are optional, and specify the ID and the name of the app, respectively. Once you run the above command, you'll see the following structure inside the project's root folder:
Used for background compatibility with Cordova tooling.
- merges: In this folder, you can add any platform-specific customization so you don't have to modify the source files every time you work with a project.
- platforms: The place where the compiled installers will be placed, in case you'll compile the project locally.
- plugins: The folder where you'll find the plugins of your project.
- www: The folder containing the source files and the configuration of the application. It contains the "css", "js", and "img" folder where you can put the respective files. In addition, it has also a "res" folder where you place icons and splashscreens.
3. Install PhoneGap Plugins
As we've seen in the introduction, our project we'll take advantage of some of the PhoneGap core plugins. To install them, you've got to use the CLI typing the command below:
phonegap local plugin add PLUGIN_REPOSITORY_URL
In the above,
PLUGIN_REPOSITORY_URL is the repository URL of the plugin you want to use. Since our project will use both the Notification and the Connection core plugins, you've got to type the following command:
phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-dialogs.git phonegap local plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-network-information.git
As the most observant of you might have noted, I didn't add the Storage plugin. The reason is that starting from version 3.0, access it is built into Cordova.
4. Add PhoneGap Frameworks
Now that we've got PhoneGap and its plugins in place, we need to add the other two libraries needed: jQuery (I'll use version 2.0.3) and jQuery Mobile (version 1.3.1).
Before we proceed, it's important to understand why I chose the 2.x branch of jQuery. jQuery has two major branches currently in development: 1.x and 2.x. The version you should use really depends on where you're using the framework and what browsers you intend to support. While jQuery 1.x supports all the versions of Google Chrome, Firefox, Safari, Opera, and Internet Explorer starting from version 6, the 2.x version dropped the support for Internet Explorer 6, 7, and 8 in exchange for a smaller size and better performance. Since we're developing a mobile application with Cordova, we don't need to worry about Internet Explorer 6-8. In fact, the Microsoft operating systems supported by Cordova are Windows Phone 7 and Windows Phone 8 that run respectively on Internet Explorer 9 and 10. Therefore, we can safely use jQuery 2.x!
jquery.mobile-1.3.1.min.css) inside the "css" folder. Finally, we place the jQuery Mobile bundled images into the "img" folder. Since we've slightly changed the native structure of jQuery Mobile, we need to adjust the paths pointing to the images inside its CSS file. We specifically need to replace the "images/" part with this string "../img/". Keep in mind that the string should be replaced 5 times.
5. Create Project File Structure
Now that we have the project framework in place, we need to create the "www" folder, the HTML files required, set the default application's icon, tweak the Adobe PhoneGap build configuration file, and change the default splash screen. That's a lot, so let's keep moving!
Over the course of this series, we'll create the following files:
- index.html: The entry point of the application, where we'll put the links to the libraries used.
- add-feed.html: This is the page containing the form used to save a new feed.
- list-feeds.html: This displays the list of the stored feeds.
- show-feed.html: This shows the entries of the given feed. In addition, it has a navbar that has a button to delete the feed, and another to retrieve more entries from the feed.
- aurelio.html: The credits page containing information about the author.
- feed.js: This file contains a class, called
Feed, used to create, delete, and retrieve stored feeds. It's based on the Cordova Storage plugin.
- application.js: This file contains another class, called
Application, that has the methods to initialize the application's pages and attach handlers to some page's elements (for example the navbar buttons previously cited).
- config.xml: This XML file contains the metadata of our project and stores settings like the app name and description.
6. Create the Home Page
index.html file. This page shows the title and the description of the application and has all the buttons for accessing the rest of the app.
The full source of the homepage is shown below:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Audero Feed Reader</title> <link rel="stylesheet" href="css/jquery.mobile-1.3.1.min.css"/> <script src="js/jquery-2.0.3.min.js"></script> <script src="js/jquery.mobile-1.3.1.min.js"></script> <script src="cordova.js"></script> <script src="js/feed.js"></script> <script src="js/application.js"></script> <script> $(document) .on('pagebeforecreate', Application.updateIcons) .one('deviceready', Application.initApplication); </script> </head> <body> <div data-role="page"> <header data-role="header" data-back-btn="true"> <h1>Audero Feed Reader</h1> </header> <div data-role="content"> <p> Audero Feed Reader is a very basic feed aggregator to keep in one place all the news and the articles you care about. </p> <a href="add-feed.html" data-role="button">Add Feed</a> <a href="list-feeds.html" data-role="button">List Feed</a> </div> <footer data-role="footer" data-position="fixed"> <h2>Created by Aurelio De Rosa</h2> <a href="aurelio.html" data-icon="info" data-iconpos="notext" class="ui-btn-right">Credits</a> </footer> </div> </body> </html>
As you can read from the code above, the buttons inside the
<header> and the
<footer> use the attribute
data-iconpos="notext". This setting allows you to hide the link's text and is very useful to save space for small screens. As I'll explain in a later part of this series, we'll target these buttons to create a more responsive interface for the application.
7. Create the Add Feed Page
This page, named
add-feed.html, simply contains the form to add a new feed. It doesn't have anything special so we can skip the discussion of this file and just show its source:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Add Feed</title> </head> <body> <div id="add-feed-page" data-role="page" data-title="Add Feed"> <header data-role="header"> <a href="index.html" data-icon="home" data-iconpos="notext">Home</a> <h1>Add Feed</h1> </header> <div data-role="content"> <p> Use this form to add a new feed Feed. It's easy as writing a name, the URL and then click "Add Feed". </p> <form id="add-feed-form" name="add-feed-form" action="add-feed.html"> <div data-role="fieldcontain"> <label for="feed-name">Feed Name:</label> <input type="text" id="feed-name" name="feed-name" required="required"/> </div> <div data-role="fieldcontain"> <label for="feed-url">Feed URL:</label> <input type="url" id="feed-url" name="feed-url" required="required"/> </div> <input type="submit" value="Add Feed" /> </form> </div> </div> </body> </html>
8. Create the Feed List Page
This page is named
list-feeds.html and is very small like the others. Inside the file we set an unordered list with the usual
<ul> element and then enhance it using jQuery Mobile setting the
data-role="listview" attribute. In addition, we add another attribute,
data-filter="true", to add a search bar for our list. As you can see, inside the
<header>, I put a button to go back to the home page. If you're an Android user, you might find this useless, but keep in mind that not all devices have a hardware button to go back. Therefore, it's absolutely essential to create a software one in your applications!
The code for this page is listed below:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>List Feeds</title> </head> <body> <div id="list-feeds-page" data-role="page" data-title="List Feeds"> <header data-role="header"> <a href="index.html" data-icon="home" data-iconpos="notext">Home</a> <h1>List Feeds</h1> </header> <div data-role="content"> <ul id="feeds-list" data-role="listview" data-filter="true"> </ul> </div> </div> </body> </html>
9. Create the Show Feed Page
This is the page responsible for displaying feed entries and is named
show-feed.html. In it we have a list, but this time we don't need a search bar. However, unlike the previous screens, this screen has a navigation bar with the two buttons described above. To create a navbar in jQuery Mobile, you've got to create a
div with the
data-role="navbar" attribute, and then place it inside an unordered list containing your buttons.
The full code of this page is shown below:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Show Feed</title> </head> <body> <div id="show-feed-page" data-role="page" data-title="Show Feed"> <header data-role="header"> <a href="#" data-icon="back" data-iconpos="notext" data-rel="back" title="Go back">Back</a> <h1>Show Feed</h1> <div data-role="navbar" class="ui-body-b"> <ul> <li><a id="show-more-entries" href="#" data-icon="refresh" data-iconpos="left">Show more</a></li> <li><a id="delete-feed" href="#" data-icon="delete" data-iconpos="left">Delete Feed</a></li> </ul> </div> </header> <div data-role="content"> <div id="feed-entries" data-role="collapsible-set"> </div> </div> </div> </body> </html>
As you can see from looking at the code, our navbar also has a class applied. It belongs to the jQuery Mobile stylesheet and it's used to apply a different theme, in this case a blue color, to highlight each of the buttons.
10. Create the Credits Page
aurelio.html is the least important of the whole application and doesn't have any exciting widget or element to describe. The only remarkable fact is the use of the attribute
target="_blank" applied to the links. This attribute is widely used among the web but, this time, I'm using it as a hook to attach a handler to all the external links. You'll learn more about this in the third part of the tutorial series.
The code of
aurelio.html is shown below:
In this the first installment of our series we've seen the features of the feed reader app and how to create the project structure. Moreover, we developed all the HTML files that will compose our app. In the second installment of this series, we'll write the business logic of Audero Feed Reader and discuss the Google Feed API. Check back soon, and thanks for reading!