상세 컨텐츠

본문 제목

Develop iPhone Web applications with Eclipse

프로그래밍/JAVA

by 라제폰 2009. 7. 28. 20:00

본문


Level: Intermediate

Adam Houghton (adam@adamhoughton.com), Senior Software Developer, SAS Institute, Inc.

29 Jan 2008

Learn to create iPhone Web sites using Eclipse, Aptana's iPhone Development plug-in, and the iUi framework. See the development of a Javadoc viewer for the iPhone, uncover tips for user interface design, and hear about the future of iPhone application development.

Apple's iPhone platform presents an interesting opportunity to developers. With a small form factor and interactive touchscreen, the iPhone and iPod Touch have won over millions of users in a short period of time. But this novel design and proprietary platform present a new set of challenges for application developers. Until Apple releases its software development kit (SDK) in February 2008, developers wishing to target the platform must create Web applications that mimic the iPhone's native look and feel.

Fortunately, a new set of open source tools is available to make this easier. Aptana's iPhone Development plug-in for Eclipse generates iPhone-specific projects and previews applications in a rotatable viewfinder. Joe Hewitt's iUi, a Cascading Style Sheets (CSS) and JavaScript framework, contains a grab bag of widgets and pages that emulate the native iPhone experience.

In this article, we use Aptana and iUi to create a new application: a simple Javadoc viewer for the iPhone. First, we design a user interface (UI) for browsing Javadoc on an iPhone, then create a custom doclet to generate the Javadoc pages from any source code. Along the way, we describe UI issues encountered when targeting the iPhone, how these open source tools can simplify development and debugging, and the future direction of iPhone development.

A quick walk through the tools

Start by installing Aptana and downloading iUi:

  1. In Eclipse V3.2, select Help > Software Updates > Find and Install.
  2. Select Search for new features to install. This window lists the sites from which you've downloaded plug-ins plus those plug-ins predefined by Eclipse.
  3. Add Aptana to this list by clicking New Remote Site and defining it with a URL of http://update.aptana.com/update/3.2/.
  4. Select the newly defined Aptana site from the list, click Next, then install all available features. Complete the window to lay down the base Aptana Editor.
  5. Restart Eclipse.
  6. Select Window > Open Perspective > Other, then select Aptana from the window. A new set of icons appears in the toolbar.
  7. Click the home icon. An overview of Aptana features appears.
  8. In the Apple iPhone Development section, click Download and Install.
  9. Install all features, then complete the window to configure Aptana with iPhone-specific features.
  10. Restart Eclipse.
  11. Download the latest version of iUi (see Resources).

When everything is in place, use Eclipse to create a new iPhone Project called iDoc, shown in Figure 1.


Figure 1. Creating a new iPhone Project
Creating a new iPhone project

Figure 2 shows the resulting project containing a simple iPhone application.


Figure 2. The resulting iPhone Project in Eclipse
The resulting iPhone Project in Eclipse

Note the syntax highlighting provided by Aptana's base editor, which supports HTML, CSS, and JavaScript.

iPhone Preview mode and application server

At the bottom of the text editor, you see the tabs Source, iPhone Preview, and each browser installed on your system (for example, Safari Preview, Firefox Preview). Click iPhone Preview to see what the sample application looks like on the iPhone. Click outside the browser to rotate the phone or click the phone title bar to hide the navigation bar. The horizontal iPhone Preview mode is shown below.


Figure 3. Horizontal view in iPhone Preview mode
Horizontal view in iPhone Preview mode

The iPhone Preview mode is a great time-saver: You can test new design ideas quickly and iteratively develop without leaving the computer. When it's time to test drive your application on an actual iPhone, Aptana's built-in application server comes in handy. Click the Run icon on the Eclipse toolbar to launch the server. Figure 4 shows the application server running in Eclipse.


Figure 4. Aptana's iPhone Application Server hosts page and creates e-mail with URL
Aptana's iPhone Application Server hosts page and creates e-mail with URL

If your iPhone is connected to your local network through a WiFi connection, it can access the URL displayed on the server window. Save yourself a step by clicking E-mail this url and sending a message to the e-mail account on your iPhone. Tap the link in the e-mail, and the application launches in the iPhone's Web browser.

iUi demo: Theater listings Web application

Although Aptana's starter application contains iPhone-specific HTML and CSS files, they are limited in functionality. A better alternative is the iUi framework, which has a rich set of custom widgets and JavaScript effects that accurately mimic the native iPhone interface.

Uncompress the downloaded iUi distribution, iui-0.13.tar, and copy the files into the iDoc Project in Eclipse. Figure 5 shows a Project containing iUi.


Figure 5. iDoc Project with iUi framework and sample projects
iDoc Project with iUi framework and sample projects

The demo Web applications for iUi are found in the samples folder, expanded above. They include a music browser, theater listings, and a Digg-like site. Using Aptana's iPhone Preview mode, we can view them in Eclipse. Figure 6 shows the search page of the theater listings Web application (samples/theaters/index.html).


Figure 6. iUi's sample theater listing Web application
iUi's sample theater listing Web application

Note how closely the demo resembles the native iPhone look and feel. These prepackaged widgets enable rapid development of iPhone Web applications.



Back to top


Designing the UI

In this example, create a Javadoc viewer for the iPhone called iDoc. The dense HTML files created by Sun Microsystems' standard Javadoc generator look great on the desktop, but are difficult to navigate and read on the iPhone. iDoc generates iPhone-friendly Javadoc — perfect for browsing application program interfaces (APIs) on the subway or letting the observer in your pair programming team help out.

iPhone human interface guidelines

Before we start designing the UI for iDoc, it's important to understand what makes iPhone development different from ordinary Web development. Figure 7 from Apple's iPhone Dev Center (see Resources) summarizes it nicely: A finger is not a mouse. This removes the pixel preciseness found in desktop applications, but opens a rich new user interaction model with taps, flicks, and pinches. Additionally, an iPhone travels with a user and is often used in distracting environments, so applications need to provide quick, easy access to targeted information.


Figure 7. A finger is not a mouse
A finger is not a mouse

Apple's iPhone Human Interface Guidelines (see Resources) define three types of iPhone Web content.

Compatible with Safari on iPhone
Any type of Web page that can be displayed correctly, even if a portion of the page relies on an unsupported plug-in like Adobe Flash or Java™ applets
Optimized for Safari on iPhone
A Web page that correctly scales content for the iPhone and doesn't rely on unsupported plug-ins
iPhone Application
A Web page that resembles a native application by emulating the iPhone look and feel and, when appropriate, integrating with iPhone services like phone, e-mail, or Google Maps

Standard Javadoc pages fall under the first category, Compatible with Safari on iPhone. They can be displayed correctly, but require a good deal of pinching and flicking to find relevant information. With iDoc, aim for a full iPhone application. Although there are no opportunities for integrating with other services, iDoc's interface feels right at home on the iPhone.

The iDoc UI

When targeting the iPhone, it's important to remain focused. Applications should accomplish specific tasks in a quick manner, not try to include every possible feature. With iDoc, users must find basic documentation about Java classes, such as class names, method names, method signatures, and comments. Present this information with three levels of navigation leading to a destination detail page.

Package navigation
Top-level packages
Class navigation
Classes, interfaces, exceptions, and errors within a package
Class detail navigation
Description, fields, constructors, and methods within a class
Detail page
Comments, signatures, and parameters

To keep iDoc uncluttered and task-focused, some traditional Javadoc features are missing. For example, package description comments aren't displayed. Because these are often uninformative (for example, acme.client contains client code) and sometimes missing altogether, it makes sense to leave them out of iDoc and simplify the interface.

For the three levels of navigation, use an edge-to-edge list. This is a familiar construct in native iPhone applications, used for browsing contacts, e-mail, and music. Edge-to-edge lists display items in equal-size rows 44 pixels high and are useful for scrolling through large amounts of information. Apple's iPhone Human Interface Guidelines provide metrics for constructing an edge-to-edge list, including font, font size, and border spacing. The iUi framework implements these metrics in CSS and the JavaScript language, allowing you to create simple HTML lists displayed like native iPhone components.

Listing 1 shows the page header, along with the first two levels of navigation for the java.applet and java.rmi packages.


Listing 1. HTML document with page header and first two levels of navigation
                
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>iDoc</title>
<meta name="viewport" content="width=320; initial-scale=1.0; 
   maximum-scale=1.0;
   user-scalable=0;"/>
<style type="text/css" media="screen">@import 
   "iui/iui.css";</style>
<style type="text/css" media="screen">@import 
   "iDoc.css";</style>
<script type="application/x-javascript" 
   src="iui/iui.js"></script>
</head>

<body onclick="console.log('Hello', event.target);">
   <div class="toolbar">
     <h1 id="pageTitle"></h1>
     <a id="backButton" class="button" 
        href="#"></a>
   </div>
  <ul id="home" title="Packages" selected="true">
      <li><a href="#java.applet">java.applet</a></li>
      <!-- more packages...-->
      <li><a href="#java.rmi">java.rmi</a></li>
  </ul>
  <ul id="java.applet" title="java.applet">
      <li class="group">Interfaces</li>
      <li><a href="java.applet.AppletContext.html">
         AppletContext</a></li>
      <li><a href="java.applet.AppletStub.html">
         AppletStub</a></li>
      <li><a href="java.applet.AudioClip.html">
         AudioClip</a></li>
      <li class="group">Classes</li>
      <li><a href="java.applet.Applet.html">Applet
         </a></li>
      <li><a href="java.applet.Applet.AccessibleApplet.html">
         AccessibleApplet</a></li>
  </ul>
  <ul id="java.rmi" title="java.rmi">
      <li class="group">Interfaces</li>
      <li><a href="java.rmi.Remote.html">
         Remote</a></li>
      <li class="group">Classes</li>
      <li><a href="java.rmi.MarshalledObject.html">
         MarshalledObject</a></li>
      <li><a href="java.rmi.Naming.html">
         Naming</a></li>
      <li><a href="java.rmi.RMISecurityManager.html">
         RMISecurityManager</a></li>
      <li class="group">Exceptions</li>
      <li><a href="java.rmi.AccessException.html">
         AccessException</a></li>
      <li><a href="java.rmi.AlreadyBoundException.html">
         AlreadyBoundException</a></li>
      <li><a href="java.rmi.ConnectException.html">
         ConnectException</a></li>
      <li><a href="java.rmi.ConnectIOException.html">
         ConnectIOException</a></li>
      <li><a href="java.rmi.MarshalException.html">
         MarshalException</a></li>
      <li><a href="java.rmi.NoSuchObjectException.html">
         NoSuchObjectException</a></li>
      <li><a href="java.rmi.NotBoundException.html">
         NotBoundException</a></li>
      <li><a href="java.rmi.RemoteException.html">
         RemoteException</a></li>
      <li><a href="java.rmi.RMISecurityException.html">
         RMISecurityException</a></li>
      <li><a href="java.rmi.ServerError.html">
         ServerError</a></li>
      <li><a href="java.rmi.ServerException.html">
         ServerException</a></li>
      <li><a href="java.rmi.ServerRuntimeException.html">
         ServerRuntimeException</a></li>
      <li><a href="java.rmi.StubNotFoundException.html">
         StubNotFoundException</a></li>
      <li><a href="java.rmi.UnexpectedException.html">
         UnexpectedException</a></li>
      <li><a href="java.rmi.UnknownHostException.html">
         UnknownHostException</a></li>
      <li><a href="java.rmi.UnmarshalException.html">
         UnmarshalException</a></li>
  </ul>

Figure 8 shows the resulting top level of navigation for selecting packages, using edge-to-edge lists.


Figure 8. Navigate Javadoc packages just like a native iPhone application
Navigate Javadoc packages just like a native iPhone application

Figure 9 shows the resulting java.rmi package displayed in iPhone Preview mode.


Figure 9. Navigate interfaces, classes, and exceptions within java.rmi package
Navigate interfaces, classes, and exceptions within java.rmi package

For iDoc's destination detail page, use another iPhone construct: a rounded-rectangle list. These lists are useful for grouping information and are found throughout the settings panels on the iPhone. Use rounded-rectangle lists for separating method signatures and listings of parameters and exceptions. In V0.13, iUi only supports rounded-rectangle lists for form input; using their elements for static text produces incorrectly formatted blocks. Extend their CSS with a custom iDoc.css file (shown in Listing 2) to add a textRow element for displaying rounded-rectangle lists with static text.


Listing 2. Custom textRow CSS extension to correctly display static text
                
/* Adding a new row CSS style to iUi for displaying blocks of text */
.textRow  {
    position: relative;
    border-bottom: 1px solid #999999;
    -webkit-border-radius: 0;
    text-align: right;
}

.textRow > p {
    text-align: left;
    margin: 5px 8px 5px 10px;
    padding: 0px 0px 0px 0px;
}


fieldset > .textRow:last-child {
    border-bottom: none !important;
}

Listing 3 shows the detail page for one of java.math.BigDecimal's constructor methods.


Listing 3. HTML detail page using textRow elements
                
<div id="java.math.BigDecimal(long,java.math.MathContext)" title="BigDecimal"
        class="panel">
    <fieldset>
        <div class="textRow"><p><b>
           public BigDecimal(long, MathContext)</b></p></div>
        <div class="textRow"><p>Translates a 
           <code>long</code> into a
        <code>BigDecimal</code>, with rounding according to the context settings.
        The scale of the <code>BigDecimal</code>, before any rounding, is zero.
      </p></div>
    </fieldset>
    <h2>Parameters</h2>
    <fieldset>
        <div class="textRow"><p><b>long val
           </b>: <code>long</code> value to be converted
         to <code>BigDecimal</code>.</p></div>
        <div class="textRow"><p><b>MathContext mc
           </b>: the context to use.</p></div>
    </fieldset>
    <h2>Throws</h2>
    <fieldset>
        <div class="textRow"><p><b>ArithmeticException
           </b>: if the result is inexact but
    the rounding mode is <code>UNNECESSARY</code>.</p></div>
    </fieldset>
</div>

Everything within the <fieldset> tag is inside the rounded rectangle, with textRow <div>s splitting the rows. Headings with <h2> tags are displayed as group labels above the lists. Figure 10 shows the resulting page.


Figure 10. Detailed view of a constructor in java.math.BigDecimal
Detailed view of a constructor in java.math.BigDecimal

With the three levels of navigation and the destination detail page, the UI is complete. iDoc lets users focus on a specific task. With the help of the iUi framework and some custom CSS, it looks like a native iPhone application.



Back to top


Developing iDoc

Now that we have designed the UI, we need code to generate HTML files. Create a simple doclet that plugs into Sun's javadoc command. Our examples use standard java.* packages, but iDoc can generate Javadoc from any source code. Use the OpenJDK source code (see Resources), as it's publicly available and the GNU Public License (GPL) V2 license lets us generate and distribute its Javadoc.

With iDoc, simply iterate over the packages and classes and call methods to print static HTML pages in the format described above. Listing 4 shows the methods for printing the destination detail pages.


Listing 4. Doclet code for outputting detail pages
                
private void printDetail(PrintStream p, ProgramElementDoc doc, 
    String id, String name) {
    divHeader(p, id, name, "panel");
    textHeader(p, null);
    textRow(p, getSignature(doc));
    textRow(p, getCommentText(doc.commentText()));
    textFooter(p);
    if (doc instanceof ExecutableMemberDoc) {
        printMethodDetail(p, (ExecutableMemberDoc) doc);
    }
    divFooter(p);
}

private void printMethodDetail(PrintStream p, ExecutableMemberDoc field) {
    if (field.parameters().length > 0) {
        textHeader(p, "Parameters");
        for (int i=0; i<field.paramTags().length; i++) {
            textRow(p, "<b>" + field.parameters()[i].typeName() + " "
                    + field.paramTags()[i].parameterName()
                    + "</b>: "
            + getCommentText(field.paramTags()[i].parameterComment()));
        }
        textFooter(p);
    }
    if (field.throwsTags().length > 0) {
        textHeader(p, "Throws");
        for (int i=0; i<field.throwsTags().length; i++) {
            textRow(p, "<b>" +  field.throwsTags()[i].exceptionName()
                    + "</b>: "
            + getCommentText(field.throwsTags()[i].exceptionComment()));
        }
        textFooter(p);
    }
}

The code is generalized such that printDetail() handles the output of class descriptions, fields, constructors, and methods. The latter two types are subclasses of ExecutableMemberDoc, so additional information is printed about their parameters and thrown exceptions.

Performance issues

GZIP compression

One simple, yet effective, performance tip is to enable GZIP compression on your Web server. Most modern Web servers provide this option, which compresses pages before they are sent across the wire to supported clients. Safari on iPhone is one of these clients. It supports GZIP decompression automatically. Simply enable GZIP compression on your Web server, and iPhone users will experience faster download times.

Aptana's iPhone Preview mode helps debug the outputted files. After each iteration, you can quickly click through the application to find inconsistencies from the designed interface. However, using Preview mode can mask performance problems: Modern computers run three to five times faster than the iPhone's 620-MHz ARM processor. Additionally, users often download pages over slow cellular networks, so it's important to run your application with an actual iPhone.

In my tests viewing iDoc on an iPhone, I find that outputting one giant HTML file causes jumpy animations and degrades performance. To fix this, create one main file for navigating package/class names, then create separate files for each class with comments and method details (see Listing 5). Although this process produces a large number of files, the individual file sizes are small, and the application runs smoothly.


Listing 5. Doclet code iterates over each package, then creates individual files for each class
                
out = new FileOutputStream(index);
p = new PrintStream(out);
printHeader(p);

PackageDoc[] packages = root.specifiedPackages();
Arrays.sort(packages);

printPackages(p, packages);

for (int i=0; i<packages.length; i++) {
    printPackageDetail(p, packages[i]);
}
for (int i=0; i<packages.length; i++) {
    ClassDoc[] classes = packages[i].allClasses();
    Arrays.sort(classes);
    for (int j=0; j<classes.length; j++) {
        // Creating a separate file for each class.
        PrintStream p2 = new PrintStream(new FileOutputStream(getFilename(classes[j])));
        printClassDetail(p2, classes[j]);
        p2.close();
    }
}
printFooter(p);
p.close();

iDoc in action

With this performance enhancement, iDoc is ready to go. Generate Javadoc for the 51 java.* and javax.* packages in OpenJDK, representing 1,304 classes, then upload everything to your Web server. This comprises more than 16 MB of files, but the main navigation page is only 112 KB, and the individual class detail pages average 13 KB each. Even when using the EDGE network, the application is quite responsive. If you've got an iPhone, visit the iDoc site (see Resources) and try it out, or you can download iDoc to generate iPhone-specific Javadoc for your own code base. Figure 11 shows the final application.


Figure 11. iPhone-ready Javadoc for all 51 packages
iPhone-ready Javadoc for all 51 packages

Potential extensions to iDoc include support for displaying Java 5 generics and smarter capturing of tags within Javadoc comments to implement links between pages. The full source code is available online (see Resources) if you're interested in adding to iDoc's functionality.



Back to top


Future of iPhone development

In October 2007, Steve Jobs announced that Apple will release an iPhone SDK in February 2008. The details are sparse as this was written in December 2007, but an SDK will allow you to create applications that run natively on the iPhone without needing Safari. Given the underlying iPhone architecture, it is likely that the development platform will be Cocoa and Objective-C, similar to Mac OS X. Recent comments by Apple executives suggest that third-party applications will need to undergo some type of certification process.

Applications requiring advanced animation, graphics, and network access will benefit from running natively. However, even when the SDK is released, Web development for the iPhone will still be an attractive proposition. Web applications are easy to create and simple to deploy. Tools such as Aptana and iUi simplify development and allow for rapid creation of Web applications. As shown with iDoc, there's no need to wait for the SDK: With today's tools, you can create fully featured iPhone Web applications with a native look and feel.



Resources

Learn

Get products and technologies

Discuss
  • The Eclipse Platform newsgroups should be your first stop to discuss questions regarding Eclipse. (Selecting this will launch your default Usenet news reader application and open eclipse.platform.)

  • The Eclipse newsgroups has many resources for people interested in using and extending Eclipse.

  • Participate in developerWorks blogs and get involved in the developerWorks community.



About the author

Adam Houghton is a senior software developer in the SAS Advanced Computing Lab and specializes in all things Java.

관련글 더보기