Real-time auctions with HTML5, PayPal and Google App Engine - Part 3

By Peter Georgeson

Overview

This series of articles explores some interesting technologies while demonstrating how to build a real-time auction application.

Part 1 described Google's Channel API and how to build a responsive, event-driven application.

Part 2 integrated PayPal's Adaptive Payments API into the sample application and demonstrated how to use the preapproval API to ensure bidders pay for purchases.

This is Part 3 and covers some techniques to improve the application's suitability for mobile platforms. Although the techniques presented here can be applied to any mobile device, the specific examples apply to the iOS family - iPhone and iPad.

Mobile Issues

In recent years, mobile users have become a significant proportion of internet traffic. Mobile applications bring their own set of challenges:

Techniques for dealing with these issues are outlined in the following sections.

Screen Real Estate

Typically, a web page that has not been optimized for mobile devices does not look good. The iPhone, for instance, defaults to having a viewport width of 980px. 980px on the desktop will be compressed to fit into the width of the iPhone. This behaviour allows most web pages to be completely visible on an iPhone screen, however often the page text is rendered in a font that is far too small. Not good!

Fortunately, it's easy to rectify this. Simply add this line to the <head> section of templates/base.htm:


<meta name="viewport" content="width=device-width, initial-scale=1.0">

Now the text is an appropriate size.

This meta tag sets the width of the viewport to be the same as the width of the device (device-width), which means that the page will not be scaled. If your web application is designed for a particular width, set the viewport to this same width and the iPhone will render your page within the size of the device.

Unfortunately, the PayPal payment screens are not yet optimized for mobile, however, the expectation is that at some point PayPal will implement this. Once they do, the full process will be mobile friendly. In the meantime, Part 2 of this series explains how to implement preapprovals. Preapprovals enable a mobile user to participate in auctions without necessarily having to go through the payment process.

Alternate Layouts

By modifying the viewport width, the page text becomes readable. The next issue is the content and layout. On the sample application, the layout on a mobile device is not great. Important information is pushed off the bottom of the screen - such as the bidding form! A page layout that is fine on the desktop is not necessarily optimal on smaller screen sizes.

CSS3 provides a way to specify conditional CSS based on the screen size. This enables us to load a different CSS file based on the capabilities of the browser. Hence you can build separate user interfaces by simply specifying different CSS.


  <link media="only screen and (max-device-width: 480px)" href="/static/small.css" type= "text/css" rel="stylesheet">
  <link media="screen and (min-device-width: 481px)" href="/static/style.css" type="text/css" rel="stylesheet">

Now we can selectively modify the mobile user interface by editing small.css. In this application, some non-essential components of the user interface are removed and the background color is changed:


#body {
  background-color: orange;
}

#header {
  display: none;
}
With these changes, the mobile interface is now simple and minimal. All the essential information fits on the screen of the mobile device.

iPhone vs Desktop interface

The major advantage of this technique is that you can keep a single code base for your user interface - differences are limited to the CSS files. A lot can be achieved with CSS rules and as long as the user interfaces don't deviate significantly, this is a suitable method.

If the intention is for the mobile interface to be completely different from the desktop interface then this technique isn't as effective.

A Native iPhone Application

Many companies like the idea of being on the app store for the marketing benefits. However, writing a completely native interface is a significant undertaking. After learning Objective-C and iOS SDK, the HTML and JavaScript interface must be converted to Objective-C. Any future changes to the interface would also need to be reflected in the native application. Porting Google's Channel API client from JavaScript would be a particularly interesting challenge.

Fortunately, it is possible to build a native iPhone application while maintaining an HTML based interface. The iPhone SDK includes a UIWebView component, which acts as a container for HTML code. A very simple iPhone app has been created to demonstrate this concept; it is included in the sample application.

The UIWebView is configured to represent the entire iPhone application. With this done, the iPhone client can be developed with the traditional web languages of HTML, JavaScript and CSS.

The important method in this sample application is the method that loads the initial contents of the UIWebView:


- (void)viewDidLoad
{
    NSString *path = [[NSBundle mainBundle] pathForResource:@"start" ofType:@"html"];
    NSData *data = [NSData dataWithContentsOfFile:path];
    [webView loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:[NSURL fileURLWithPath:path]];
    [super viewDidLoad];
}
start.html has been added as a resource to the project. start.html simply redirects the browser to the main application page:

<html>
  <head>
    <script>
      function init() {
        document.location = "http://localhost:8083/";
      }
    </script>
  </head>
  <body onload="init()">
    <p>Loading...</p>
  </body>
</html>
Although this code simply redirects to the online site, including an offline page in the application enables something to be displayed immediately, even if there is no network connection. Potentially, all the assets associated with the web application could be moved offline and added as resources to the iPhone application: all HTML, JavaScript, CSS and image assets. This provides a major boost to application performance - the whole application can load immediately, without waiting on the network.

By default the UIWebView widget doesn't include any of the usual chrome that comes with the mobile browser, in particular the forward, back and reload buttons. This enables a more native look and feel to be implemented, however if you intend to do away with these buttons, you must ensure the user can still navigate the application. In the sample iPhone application, if the user visits their profile page, there is no way to return to the main bidding page without the addition of extra navigation.

Using an embedded web view to build a native application provides some important advantages:

HTML5 - Local Storage

Mobile users typically have limited bandwidth. They may also have periods where the network is unavailable. For this reason, the HTML5 features of local storage and application caching can be useful.

Web developers typically use cookies to identify a user and store user-specific state. However, cookies can only hold a few kilobytes of data. If this state is more than a few kilobytes then the data must be stored on the server. If we then want to provide this data to the user, it must be downloaded by the user. If there's a lot of data, and the user has limited bandwidth, it won't be a great user experience.

Local Storage is a simple alternative and is available on all current browsers. Local Storage makes available to the browser a persistent keystore. The keystore is:

Local Storage is demonstrated on the sample application by storing a user's bid history locally. Rather than ask the server for what could be a large amount of data and time consuming request, each bid is recorded using Local Storage. Now retrieving a users bid history uses no bandwidth, and is lightning fast.

This is one example of using HTML5 to improve the mobile user experience.

For all the implementation details, refer to the sample code. The main JavaScript method:


  history = function( amount ) {
    var list, li = '';
    list = JSON.parse( localStorage['history'] );
    if ( list === null ) {
      list = [];
    }
    if ( amount ) {
      list[list.length] = { 'item': item, 'amount': amount };
      localStorage['history'] = JSON.stringify( list );
    }

    for ( i in list ) {
      li = '<li>' + list[i]['amount'] + ' for ' + list[i]['item'] + '</li>' + li;
    }
    document.getElementById('history').innerHTML = '<ul>' + li + '</ul>';
  }
Local Storage values are strings, so JSON is used to convert the bid list to and from the stored string.

Conclusion

Mobile users are an increasingly important part of web traffic. This part of the tutorial outlined some of the techniques that can be used to help your webapp run smoothly in the mobile space. This article demonstrated that it is feasible to implement a web based payment application that provides a suitable user experience to mobile users.

This is the final article in the series. This series integrated some interesting new technologies with PayPal's adaptive payments to build a real-time web application that runs on mobile devices.

Further Details