Porting Javascript Applications to the iPhone

Tom examines the iPhone's web capabilities by porting a web-based application to the mobile device.


October 16, 2008
URL:http://www.drdobbs.com/architecture-and-design/porting-javascript-applications-to-the-i/211200910

Tom Thompson is the head of Proactive Support for embedded products at Freescale Semiconductor. He can be reached at [email protected].


What a difference a few years can make. Case in point: The way you implement mobile solutions for enterprise applications has changed dramatically. What caused this shift? The iPhone did, but probably not for the reasons you expect.

In my article "The Android Mobile Platform" (www .ddj.com/mobile/210300551), I mentioned that the iPhone liberated the mobile phone UI, expanding its capabilities beyond that of a keypad and function buttons. However, the iPhone changed the rules for writing mobile solutions in another way—the iPhone's Mobile Safari browser is a fully featured web browser. Its ability to view many Internet web pages and execute their scripts opens the possibility that the iPhone can handle certain corporate web-based applications. In this article, I examine the iPhone's web capabilities by porting a web-based problem-reporting form to it.

I admit when the iPhone was first pitched as a web-application platform, I was among many who clamored for the ability to write native iPhone applications. The phone runs a stripped-down version of Mac OS X, after all. Fortunately, after a year Apple has allowed us to do just that. In the interim, however, I've had an attitude adjustment in that I believe the iPhone can also serve—within limits—as a decent web-application platform. To understand my change of heart, some background information is in order.

Reports From the Field

The company I work for produces microcontroller units (MCUs). Ideally, these MCUs—and the development tools that write the embedded programs that execute on them—work perfectly. Realistically, problems happen. Much effort is put into collecting problem reports on the silicon and software, then routing this information to the appropriate engineering team. The team is responsible for correcting the problem, or devising a work-around. Often our field engineers transmit problem reports straight from the customer's site while the details are still fresh, and to get a team working immediately on a solution.

Currently, these problem reports, known as "Service Requests" (SRs), are filed electronically using a HTML/Javascript web page that executes in a laptop's web browser. This scheme avoids application and vendor lock-in, and the code is relatively easy to maintain. This solution works well—as long as you can access the customer's intranet or WiFi network. However, customers might deny our field engineer access to their network for reasons of security. Using an IT-department-certified smartphone to by-pass this connectivity problem by sending the SR through a carrier's cell towers is the obvious next step.

Several years ago, I was asked if the company's SR web page could be migrated to smartphones. A key concern was to avoid vendor lock-in. At the time, the choice was simple: Use Java Mobile to write the application. It would run on any smartphone or Blackberry with Mobile Java support. Due to other higher priority projects, the project was shelved.

Time passed and I got my hands on an iPhone. I was impressed at how many web pages it could display and interact with. The capabilities of its browser got me to wondering: How difficult would it be to port that SR web page to the iPhone? I decided to do a proof-of-concept rewrite of its code and find out.

Mobile Safari Overview and Behavior

First, let's get the nomenclature straight. While Apple calls an appropriately designed web page for an iPhone an "iPhone application," I'm going to stick with the term "web page" because in the end, no matter how well the web page integrates into the iPhone's look-and-feel, that's what it is.

Mobile Safari brings lots of features to the table for developers. It uses the same WebKit rendering engine that the desktop version of Safari uses. It's also compliant with a number of the latest web standards: HTML 4.01, XHTML 1.0, CSS 2.1 and partial CSS 3, Document Object Model (DOM) 2, and ECMAScript 3, a Javascript standard. Mobile Safari also supports the AJAX XMLHTTPRequest remote scripting object. These features let the browser render most web pages accurately and manage interactive script sessions.

You probably noticed the word "most" in that last sentence. It's there for a reason. Mobile Safari doesn't support Java applets, nor (at this time) does it handle Flash content. The browser is unaware of the phone's filesystem, so there's no downloading of plugins or other files. However, it does support cookies.

Another difference is that in Mobile Safari, certain browser events have changed or have disappeared in order to support Apple's gestures interface. For example, scrolling through a web page's content by use of a finger flick requires that the iPhone's gesture interface capture and consume events that might normally be construed as mouse events. Most mouseover events, if they appear in the browser at all, are now mapped to mousedown events. For the same reasons, the hover style is gone. If your web page uses mouseover events to implement menu choices, you need to rework the Javascript handlers to respond to mousedown events or to clickable elements instead. On the positive side, the form and document elements produce the usual onblur, onchange, and onfocus events.

Finally, Apple's human interface guidelines dictate that iPhone web pages should be small, and focussed on doing one thing very well. There are valid reasons for this:

In short, the iPhone's small screen, varying network speeds, and limited processing throughput dictates that you keep your web pages small and simple. You can link to other, separate pages, but they should also follow these guidelines. Lengthy page loads and with sluggish responses are only going to frustrate users so that they don't use your web application.

Design Considerations

The original SR web page was an HTML form that presents an array of drop-down menu elements, along with several text fields where you can enter information, as in Figure 1. Other fields display explanations that help guide users. The form relies on CSS to provide some styling, and it uses the display property to reveal or hide form elements, depending upon the choices the field engineer makes. The page gathers the information entered (such as the MCU type and the team assigned to the problem) and massages the data into a text-formatted e-mail that the company's CRM system can read. All the engineer does to complete the report is inspect the e-mail for errors, then send it to our CRM system, where the SR is logged into a database and the selected team notified.

My plan was to overhaul the SR's UI because the layout of the web page's elements were made for a large laptop screen, and not for a mobile phone. The iPhone has a 320×480-pixel screen, which is large by mobile phone standards, but still much smaller than a laptop screen. Rather than try to pack everything onto the small screen, I would instead display the array of choices as a list, where each list element serves as a link to a separate page. I wanted the web page's iPhone-based front end to gather the SR information into the same Javascript variables used by the original SR form's back-end scripts. I could then re-use the field-tested back-end functions to reformat the data for the CRM system. Along the way, I expected to contend with the changes in the browser's event behavior, plus any quirks Mobile Safari threw at me.

Some initial tests with simple HTML forms showed that Mobile Safari could present the required text fields and drop-down menus that the SR page used. However, the layout of these forms on the iPhone's screen looked like something you'd see on a desktop browser and not at all like an iPhone app. For the sake of consistency, Apple promotes the idea of having your web page resemble regular iPhone applications as much as possible. Oddly, the company doesn't offer any framework to help you do this.

Figure 1: A portion of the original Service Request form as it appears on a laptop browser.

Because I didn't have the time or expertise to write such a framework, I did the next best thing—I did a Google search for one. It turns out that there are several: the iPhone UI (iUI), originally written by Joe Hewitt and now maintained by Google code (code.google.com/p/iui), the iPhone UI Universal Kit written by Diego Lafuente (www.minid.net/iphone), and WebApp.Net, written by Chris Apers (webapp.net.free.fr). I chose iUI because it's fairly simple, and its creator wrote Firebug, a FireFox add-on that lets you debug Javascript code in the browser (www.ddj.com/architect/196802787).

Framework Features

The iUI framework consists of a mixture of CSS styles and Javascript functions. These provide a set of style selectors that you apply to your page's HTML elements. The framework then uses Javascript to manipulate the page's document tree to modify its look. The appearance and behavior of these modified elements mimics that of the iPhone UI. For example, an ordered list of hyperlinks becomes the familiar iPhone list with arrows used to jump to other pages of a program.

There are style selectors for setting up a navigation bar, lists, and hyperlinked lists of information. Other styles help construct panels that contain controls, display information, or provide buttons.

Other iUI features that assist you with writing iPhone web pages are:

To use iUI, you reference its CSS styles file (iui.css), and Javascript functions file (iui.js) inside your web page's header, bracketed by the appropriate <javascript> and <style> tags.

To recap, you write your iPhone page using HTML elements and tag them with iUI styles. After you put the interface together, you then write your own Javascript functions that carry out the page's intent. When the page executes on the iPhone, it looks and behaves like an iPhone app, thanks to the iUI framework.

Writing and Testing Code

Because iPhone web pages render in a browser, you can use a standards-compliant desktop desktop browser such as FireFox 3.x, Safari 3.x, or Opera 9.x to write and test a page's code. The iUI framework makes the web page resemble an iPhone screen even on the PC, so you can also work the kinks out of your web page's layout before it is ever loaded onto an iPhone. Because IE 6 and 7 don't support many of the standard CSS selectors, iPhone web pages won't render properly in this browser. Simply put, don't use IE.

I started my code port using FireFox 3 along with Aptana's Firebug to help debug the Javascript functions. While browsers are quite robust in rendering HTML with unbalanced or mangled tags, for a Javascript error they simply abort and don't render the page, a behavior that can drive you mad. Firebug is really good at catching Javascript errors, ranging from the simple typo to a reference to an object that doesn't exist, something that can easily happen you're figuring out how to access objects on the document tree. You can step through the code and watch variable values change as the Javascript executes, which is a good way of confirming that the code really works, rather than it just happens to work.

I was able to get a list display working quickly by using the toolbar style and writing a main list with the <ul> and <li> tags. Although this was only a proof-of-concept program, I then reworked the code so that Javascript built the list dynamically, using a for loop for this purpose. I wanted to see if iUI was capable of handling a dynamically changing list, and the framework passed the test. Listing One(a) (available online at www.ddj.com/code/) shows the HTML unordered list code that generates the main list, while Listing One(b) (also available online) shows the Javascript that generates the main list dynamically. Figure 2 shows the rendered result from both listings.

Figure 2: The code in Listing One rendered on the Mobile Safari on an iPhone

Making a selection on this main list takes you to other screens with the relevant controls. For the processor, team, report type, and e-mail address where the engineer chooses an item from a list, I used the drop-down menus provided by the <select> tag. For the SR's priority level where there are several mutually exclusive choices, I opted to use radio buttons, which were handled by the <input type="radio"> tag.

For those fields where text was entered, I used a form with tables for setting up the required fields. I could have used CSS to arrange these elements, but it was easier to reuse the table layout from the existing SR code. With some modifications, I got the subject and description fields, plus the character counter display to where it closely matched the original layout. See Listing Two (available online) for the code, and Figure 3 for the end result.

Figure 3: The code in Listing Two rendered on the iPhone. While I made it resemble the original SR page (Figure 1), this isn't a requirement.

The submit screen was straightforward, as this was just some buttons within a form. I specified a bluebutton style for the Submit button, as the blue color indicates the preferred choice (much like an OK button on the Mac OS UI). I had to add some Javascript code to handle the onsubmit event. This code invokes a verify function. For any missing information, the function displays an alert for the item in question and the submit process aborted. If all of the inputs were valid, the function instead packages the information for the e-mail's subject and body, launches the e-mail application, and drops the text into it.

One minor problem I had with iUI was in accessing the content of various objects on the document tree. Although the iPhone web page appears as a main list screen with links that jump to other web pages with controls or text fields, the reality is that the application is just one big web page. The page anchors that comprise the main list point to other elements on the page, which might be more lists, controls, or forms. Because iUI modifies the document tree to make the designated elements appear as separate screens, accessing them through the document objects array was problematic. The solution was to assign the desired objects an ID, and then use the getElementById() method to access the object. For those elements that are part of a form, the usual techniques of accessing arrays on the document tree worked.

Acid Test with Mobile Safari

Once I got the web page working reliably on both the FireFox and Safari desktop browsers, it was time to try the web page where it really counted: Mobile Safari on the iPhone. I placed the program on a web site, downloaded it to the iPhone, and tapped away at the screen. When I tapped Submit, the verify function insisted I hadn't made any choices. Because the code's logic checked out on the desktop browsers, I knew the problem was rooted in changes to browser events for drop-down menus, since I relied on onchange events to transfer the choices into variables.

However, after some tests, I discovered that the drop-down menus weren't generating any events at all. I went to iPhoneDevWeb, a Google group where developers discuss issues with iPhone web page development. I spotted a report that explains where a bug in Safari prevents drop-down menus from producing events if they have a size attribute. It took only seconds to delete this attribute with the editor, and the drop-down menu choices began working.

The next issue I had was with the radio buttons. Rather than small circles, they were stretched across the screen. By adding table cells, I could get the buttons to appear less elongated, which hinted that something in iUI was the culprit. A query on iPhoneDevWeb got me a response in about a day. This was a known problem with the input selector in iUI's CSS file. A suggested work-around was to modify the CSS to position the button with margins. I decided to go in search of custom radio buttons instead, as the typical browser radio button doesn't hew closely to the iPhone interface.

Soon I found Checkbox and Radio Input Replacement (CRIR) written by Chris Erwin. This is more CSS and Javascript code that generates custom buttons and checkboxes. I dropped the radio button code into the program and got it working in short order. The only changes I made were to replace the small, light-green button image with the blue button image that appears in the Apple Mail application. I haven't had any problems with iUI and CRIR's styles and code creating conflicts. You can download CRIR from Dr. Dobb's (see www.ddj.com/code/), with the modified button images, or at www.chriserwin.com/scripts/crir.

Finally, when I attempted to enter text into a description field, the virtual keyboard kept disappearing after I typed a character. This I traced to the character count routine, which removed the focus from an input text field, updated the character count field, and reestablished the focus on the text field. This sequence of events interfered with the virtual keyboard's operation. The solution was to modify the counting function so that it didn't alter the focus.

After these hurdles were cleared, I was able to tap in various choices, hit submit, and the iPhone's Mail application appeared, with the message ready to go. The SR form's code could stand some improvements, but it demonstrates that the iPhone would be a suitable platform for making field reports. All that remains to do is add the back-end formatting code, but that will wait until the IT department approves the iPhone as secure enough for corporate work. For more tips on writing iPhone web pages, see the sidebar, "Steps to Writing an iPhone Web Page."

Better Browsing on Mobile

The partial port of the SR web page shows that it's not difficult to move a subset of a company's web-based applications onto the iPhone. I was able to locate and use an off-the-shelf framework and custom Javascript software to impart an iPhone look and feel to the SR web page. Would using an iPhone for SR reporting risk vendor lock-in? Not really, which brings us back to the point I made at the start of this article. Apple's iPhone has raised the bar on what's acceptable for a smartphone browser. Mobile users will demand that their browsers be fully capable of viewing the web—albeit painfully slow at times—and executing light-weight web applications. Over time, the performance of both the platform and Javascript will improve; thereby expanding what a mobile phone is capable of doing for us. It should come as no surprise that Apple's added SquirrelFish, a high-speed Javascript interpreter, to the WebKit rendering engine.

You can expect other smartphone vendors to improve the capabilities of their browsers as fast as they can. When that happens, then we'll run web apps on any phone that we choose. That's an outcome that will be good for all of us.

Steps to Writing an iPhone Web Page

1. Prototype and write the page's code on a standards-compliant desktop browser, such as FireFox 3 or Opera 9.x I prefer FireFox because then I can apply Aptana's Firebug to debug the Javascript. Note that for these two browsers that iUI's buttons don't render well, but it's good enough for code testing.

2. If you haven't already, modify the application's interfaces so that they don't use mouseover events.

3. Test and fix the page with the desktop version of Safari 3.x. The iUI buttons render fine on this browser. Clean up any quirks with events or side-effects to CSS selectors.

4. Do final test and revisions on the iPhone. Be prepared for another round of fixes for quirks and CSS side-effects. Also, you may have to tweak the interface for the small screen. Don't forget to re-orient the phone and verify that you haven't hard-coded the screen positions of any of the application's elements or controls!

Terms of Service | Privacy Statement | Copyright © 2024 UBM Tech, All rights reserved.