DOWNLOAD
 Oracle JDeveloper Studio Edition
 Sample iPhone CSS
   TAGS
mobile, adf, All
Developer: Java

Developing for the Apple iPhone with Oracle JDeveloper and ADF

by Joe Huang

Any developer can rapidly create a compelling iPhone Web app today, using Oracle JDeveloper and ADF.

Published December 2008

The Apple iPhone, since its initial introduction in July 2007, has become the fastest selling smartphone in the 18 months of its existence. A key factor in its success is its powerful Safari Web browser that allows users to view virtually any page on the Web, with full support of JavaScript and AJAX features typically found on desktop browser only. This article will focus on using Oracle JDeveloper and Oracle Application Development Framework (ADF) Mobile to develop a mobile Web application optimized for the iPhone.

Challenges

Designing a Web application varies greatly for a mobile user who accesses the Web using the 3.5-inch iPhone screen, versus for a sedentary user access the Web using a 22-inch LCD monitor. This offers an interesting challenge to Web developers, since Web development tools on the market today fit into one of these two categories:

  • Tools that target the desktop Web browser: These tools fully leverage the AJAX/JavaScript capabilities offered by these desktop browsers. They also focus on developing user interface intended for screen size of 17-inch or resolution of 1024X768 or larger.
  • Tools that target the HTML mobile Web browser: These tools focus on delivering user interfaces to the small (240X320) screen. They also use a least common denominator approach in delivering a basic HTML content to all mobile browsers
  • .
These two tools translate into Web sites that either deliver a sub-optimal user interface and large page download, or plain HTML pages that do not leverage any advanced AJAX features that Safari browser supports.

The Oracle ADF Mobile Browser client, however, enables developers to leverage the AJAX capabilities of the iPhone Safari browser, while maintain complete compatibility with mobile browsers that can only handle plain HTML or WAP 2.0 contents. Furthermore, it helps developers create user interfaces that are optimized for iPhone screen size and mobile Web use.

Mobile Development Basics in Oracle ADF

Oracle ADF supports mobile application development through Oracle ADF Mobile. The cores of mobile support reside in the JavaServer Faces (JSF) mobile render kits delivered through MyFaces Trinidad components, as well as in Oracle JDeveloper design time support. Here are just some of the key features delivered by ADF Mobile:

  • Browser User Agent Detection and Capabilities Delivery: Mobile render kits of Trinidad components would determine client browser types by detecting user agent, and then deliver contents based on the capabilities of the detected browser. For example, when rendering for mobile browsers that do not support full AJAX capabilities, partial-page refresh support is disabled automatically. While this mechanism supports a large number of mobile browsers, they roughly fall into the following categories:
    • iPhone Safari Browser
    • BlackBerry Browsers
    • Nokia S60 Browsers
    • Windows Mobile Browsers
    • Basic HTML Browsers
  • Mobile Browser Rendering Optimization: Each mobile browser differs in how various UI components are supported, and each mobile device have different form factors and resolutions. Trinidad components would render these UI elements differently to ensure optimized display and layout of the user interface, thus insulate developers from having to consider variation in each of the target mobile devices.
  • Full support of ADF Model: All of the ADF Model and Business Logic components are supported for mobile development, with the same design time, drag-and-drop support in JDeveloper.
  • Mobile View Creation and Component Palette: The “Create JSF Page” dialog box in JDeveloper allows the developer to select mobile devices as the intended target. Once set, component palette would only list supported components on a mobile browser
  • .
  • Screen Resolution Support in the View Editor: The developer can set the size of the view editor in Oracle JDeveloper to approximate the size of a mobile device screen. This feature provides developers an approximate idea of how a view would look like on an actual mobile device.
There are also some limitations around mobile support:
  • Only Trinidad components contain render kits for mobile devices. Oracle ADF Faces components currently do not contain mobile-specific render kits.
  • A subset of Trinidad components are supported on mobile devices. Furthermore, there are certain limitations for a few supported Trinidad components as well. For details, please refer to the ADF Mobile Component Tags Summary page on the Oracle Technology Network Website.

Developing an Oracle ADF Mobile Application Optimized for iPhone

High level steps to develop an iPhone-optimized mobile application using Oracle ADF and JDeveloper are as follows:

  1. Develop or re-use existing business logic components: Because ADF Mobile is fully compatible with ADF Model and business logic components, the developer can simply re-use any existing business logic components from other projects. Furthermore, JDeveloper feature that supports drag-and-drop of Data Controls to the view editor is fully supported.
  2. Develop page flows and views for the mobile application: The process of developing page flows and views for a mobile application is basically the same as developing for a JSF application. One useful feature in the view editor is the ability to set the size of the canvas to approximate mobile devices' resolution. Oracle JDeveloper supports a handful of common mobile resolution, and iPhone resolutions can be manually added.
  3. Optimize for iPhone Safari browser: a few techniques can be used to achieve iPhone native look-and-feel, interacting with iPhone services, and improve page transition user experiences.
Details about adding view editor resolutions and iPhone optimization techniques are described below.

Adding iPhone Resolution to the View Editor

Screen resolutions list in the View Editor provides a visual aid for developers when designing views. Oracle JDeveloper provides support for the following resolutions out-of-box: 240x240, 240x260, 240x320, and 320x240. iPhone supports a 320x480 resolution.

Figure 1

To add iPhone resolution to the View Editor:

  1. First, locate and copy the following file to a temporary location. This is the JDeveloper extension file that provides mobile development support in Oracle JDeveloper:
    <JDeveloper Install Home>/jdev/extenstions/oracle.wireless.dt.jar
                                        
  2. Open the jar file using your favorite unzip program, and locate the file dc.xml. Open the file in a text editor or from Oracle JDeveloper. Please note the lines that define the various device resolution entries in the View Editor. For example:
    <reference-device name="320 X 240" displayable-name="320 X 240" width="320" height="240" TablesCapable="true" />
                                        
  3. Insert the following line just above the entry for 240x40 resolution:
    <reference-device name="320 X 480" displayable-name="320 X 480" width="320" height="480" TablesCapable="true" />
                                        
  4. Save the updated dc.xml file back into the oracle.wireless.dt.jar file. This can be done by either opening the file directly from the unzip program and then save the file when prompted, or add the file back into the jar file using your favorite unzip program.

  5. Make a backup copy of the original oracle.wireless.dt.jar file in the jdev/extensions directory first. Then copy the updated oracle.wireless.dt.jar back into the jdev/extensions directory
  6. .
  7. You will need to re-start Oracle JDeveloper to see the additional entry in the View Editor resolutions drop-down list box.

Achieving iPhone Native Look-and-Feel

Skinning allows an Oracle ADF Mobile application to take on iPhone native look-and-feel using Trinidad components. Furthermore, it allows the same set of UI components to take on platform native look-and-feel, without needing to create multiple versions of the same application for different mobile devices.

The first step in skinning for iPhone is to implement logic that would allow a JSF application to apply different style sheets for different mobile browsers during run time. Typically an Oracle ADF Mobile application needs to support more than one type of devices, and it would be impractical to define a style sheet that works well across multiple devices. To do that, first a Managed Bean should be created for the page flow of the application, where one of the methods needs detect the browser type, and return the name of the skin family that will be used for that platform. This method would be invoked in the Trinidad-config.xml file; for example:

<skin-family>#{AgentUtil.phoneFamily}
                                
Where AgentUtil is the class name of the Managed Bean, and phoneFamily is the method that returns the skin family as a string. The various skin families are defined in the Trinidad-skins.xml file, as well as the corresponding location of the CSS file within the project. For example, for iPhone, skin family can be defined as:
<skin>
                                
<id>iphone</id>
<family>iphoneFamily</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name> styles/iPhone.css</style-sheet-name>
</skin>
The AgentUtil.phoneFamily method would return iphoneFamily when iPhone is used. This would cause the style sheet located at styles/iPhone.css to be used. A sample code snippet for the AgentUtil.phoneFamily method is shown below; please note that the sample code only contain cases for iPhone, Symbian, and all other mobile browsers. You may add additional browsers as necessary.
 private String IPHONE_SKIN = "iphoneFamily";
                                
private String SYMBIAN_SKIN = "symbianFamily";
private String DEFAULT_SKIN = "minimalFamily";

public String getPhoneFamily() {
if (phoneFamily.isEmpty())
{
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest req =
(HttpServletRequest)fc.getExternalContext().getRequest();
String agent = req.getHeader("User-Agent");

if (agent != null && agent.indexOf("iPhone") > -1) {
phoneFamily = IPHONE_SKIN;
} else if (agent != null && agent.indexOf("Symbian") > -1) {
phoneFamily = SYMBIAN_SKIN;
} else {
phoneFamily = DEFAULT_SKIN;
}
}
return phoneFamily;
}

One note about the function agent.indexOf(“<UA String>”).   This function would use the input <UA String> to match against the User Agent field of the browser that's making the request.   This function performs a partial match – for example, in the example agent.indexOf(“iPhone”), this function would check the entire User Agent string of the browser against the pattern “iPhone”.   If a match is made, i.e. the user agent contains the string iPhone, then the function would be return -1.   You may specify as much or as little of the string in this field as necessary, as long as the return guarantees the match you are looking for.   While you should specify the UA string that works in your test case, here are some patterns that are commonly used:

  • iPhone: Used to identify all iPhone Safari browser
  • Symbian: Used to identify all Nokia S60 browsers
  • BlackBerry9000: Used to identify all BlackBerry 9000 series browsers
  • BlackBerry88: Used to identify BlackBerry 8800 series browsers
  • BlackBerry83: Used to identify BlackBerry 8300 series browsers
  • BlackBerry: Used to identify all other BlackBerry browsers
  • Windows CE: Used to identify all Windows Mobile browsers
  • Android: Used to identify the WebKit based browser in Android

Detailed instructions will be published in the next version of Oracle ADF Mobile Developer Guide . Further details of how to define CSS files for Trinidad-based application, please refer to this doc.

Implementing Common iPhone UI Elements Using Skinning and Trinidad Components

The next step is to achieve the iPhone native look-and-feel is to define the style classes in the style sheet that would support the creation of common iPhone UI components. There are basically three common UI elements around in an iPhone native application: Navigation Panel Lists, Field Set Panel, and Navigation Bar. Let's look at each of these elements in more detail.

Navigation Panel Lists

Navigation Panel Lists displays a list of data as a one column table, where each row contains data from multiple columns. It supports the scenario where a user browser through a list of summary data, and select a row to reveal additional detail associated with that row. In the example below, the Panel List displays a list of houses on sale.

Figure 2

Corresponding code is as follows:
<div class="panelBase">
                                
<tr:table value="#{bindings.HouseByZip1.collectionModel}"
var="row"
rows="6" width="100%"
horizontalGridVisible="false">
<tr:column sortProperty="Price" sortable="false">
<tr:panelGroupLayout layout="vertical" styleClass="listing">
<!—Place a small image in each row -->
<!—row.image returns path to the image -->
<tr:image styleClass="listingImage"
source="#{row.Picture}"/>
<!—Main text for each row is a commandLink -->
<!—“goIntro” navigates to another view-->
<tr:commandLink text="#{row.Street}"
styleClass="listingLink"
action="goIntro">
<!—Save Data from selected row to a session variable-->
<tr:setActionListener from="#{row}"
to="#{sessionScope.houseDetails}"/>
</tr:commandLink>
<tr:outputText value="#{row.City}, $ #{row.Price}, #{row.Sf} Sq.Ft."
styleClass="listingDetails"/>
</tr:panelGroupLayout>
</tr:column>
</tr:table>
</div>
For the definition of the style classes such as listingImage, please use this link to download a sample iPhone CSS file.

Field Set Panel

Field Set Panel is typically used to display detailed information about an instance of data, and may provide links that navigates to another screen or view that displays related detailed information. An example of the Field Set Panel is as follows; following the example above, this view displays detailed information about a house, as well as links to additional details about the house:

Figure 3

A snippet of corresponding code is as follows:
<div class="panelBase">
                                
<tr:panelCaptionGroup>
<div class="row">
<tr:outputText styleClass="labelText" value="Street:"
truncateAt="0"/>
<tr:goLink styleClass="messageLink"
destination="http://maps.google.com/maps?q=
#{sessionScope.houseDetails.Street},+
#{sessionScope.houseDetails.City},+
#{sessionScope.houseDetails.Zip}"
text="#{sessionScope.houseDetails.Street}"/>
</div>
<div class="row">
<tr:outputText styleClass="labelText" value="City:"
truncateAt="0"/>
<tr:outputText styleClass="messageText"
value="#{sessionScope.houseDetails.City}"/>

</div>
</tr:panelCaptionGroup>
<tr:panelCaptionGroup>
<div class="row">
<tr:outputText styleClass="labelText" value="Price($):"/>
<tr:outputText styleClass="messageText"
value="#{sessionScope.houseDetails.Price}"/>
</div>
......
</tr:panelCaptionGroup>
</div>
Note that the panelBase style provides the pin-strip background of this screen. The two panelCaptionGroup controls breaks the display of data into two groups. Lastly, the street field is a tr:goLink component that can invoke iPhone Google Maps application. This functionality will be explained in the next section.

For the definition of the style classes such as listingImage, refer to the sample iPhone CSS file.

Navigation Bar

Navigation Bar provides the primary navigation mechanism for an iPhone application. In previous examples, navigation bar is located on the top of the screen, and provides finger-clickable buttons that would bring up another view. Let's look at the navigation bar in more detail:

Figure 4

Code for the navigation bar is as follows:
<tr:panelHeader text="Details" styleClass="toolbar" rendered="true">
                                
<tr:commandLink text="Agent" styleClass="button"
disabled="false"
rendered="true"
action="toAgent"/>
<tr:commandLink text="Intro" styleClass="backButton"
disabled="false"
rendered="true"
action="backtoIntro"/>
</tr:panelHeader>
Again, the definition of the style classes such as listingImage can be found in the sample iPhone CSS file.

Interacting with iPhone Services

Mobile device browsers typically provide a couple of basic interaction with on-device services, such as telephony functionality and email functionality. iPhone takes it one step further by adding interaction with iPhone Google Maps application. Leveraging these functionality using Oracle ADF and JDeveloper takes just a few lines of code. With easy access to the binding layer where data such as phone number and address resides, Oracle ADF and JDeveloper makes it very easy to allow users to, say, dial a phone number residing in a database field.

Telephony Service

iPhone Safari has built in capability of recognizing phone numbers on a page, and allows user to click and dial on that number. This capability does not always work, however. If a phone number is simply displayed in an outputText field, there is no guarantee that iPhone will recognize it as a phone number.

To ensure that iPhone recognizes a phone number, developer should display the phone number in a tr:goLink component, and add tel: to the destination attribute of goLink. The sample code to dial a phone number contained in the session variable houseDetails and field AgentPhone:

<tr:goLink styleClass="messageLink"
                                
destination="tel:#{sessionScope.houseDetails.AgentPhone}"
text="#{sessionScope.houseDetails.AgentPhone}"/>
Additionally, iPhone provides partial support for the RFC 2086 protocol, so it is possible, for example, to dial a phone number, pause for a few seconds, and then dial an extension. The phone number may also contain letters, which would cause iPhone to dial corresponding number for these letters. To illustrate this point, let's look at this sample code with a fake phone number:
<tr:goLink styleClass="messageLink"
                                
destination="tel:1-800-use-jdev;pp8”
text="1-800-use-jdev"/>
This would cause iPhone to dial 1-800-873-5338, wait for 2 seconds (pp), and then dial 8.

Email Client

iPhone Safari browser provides interface to iPhone email client as well. To invoke the email client with an email destination filled out, developer would use a tr:goLink component to display the email field, and add mailto: to the destination attribute of the component, such as:

<tr:goLink styleClass="messageLink"
                                
destination="mailto:#{sessionScope.houseDetails.AgentEmail}"
text="#{sessionScope.houseDetails.AgentEmail}"/>
When a user links on this goLink, iPhone Email client will be started, and the To: field would be populated with the content of the AgentEmail variable.

iPhone supports population of other email fields as well. The developer would simply append the following to the destination attribute of the goLink component:

  • Add multiple recipients: simply append additional email addresses separated by a comma (,)
  • Email subject: subject=<subject text>
  • Cc recipients: cc=<Email Addresses>
  • Bcc recipients: bcc=<Email Addresses>
  • Message text: body=<Message Text>
Each of the fields would need to be separated by a “?” character.

For example, the following code would pre-populate an email with a subject, cc recipients, and message text:

<tr:goLink styleClass="messageLink"
                                
destination="mailto:john.doe@oracle.com,
jane.doe@oracle.com?subject=Questions?
cc=myname@myhome.com?
body=I have questions for you”
text="#{sessionScope.houseDetails.AgentEmail}"/>

iPhone Google Maps

iPhone Safari browser can intercept calls to http://maps.google.com, and invoke the Google Maps application on the iPhone instead. There are partial supports for dropping a pin at a specified address in the Google Maps application. Once the pin is dropped, iPhone user can use GPS and “getting directions” functionality to navigate to that address, and even look at what the address looks like at the street level.

To access this functionality, developer would use tr:goLink component, and populate the destination attribute of the goLink component with an URL to Google Maps and the address. The Google Maps URL needs to be in this format:

http://maps.google.com/maps?q=<Address_Field>
                                
For example, the following will drop a pin at a location specified by session variables houseDetail.Street, houseDetail.City, and houseDetail.Zip.
<tr:goLink styleClass="messageLink"
                                
destination="http://maps.google.com/maps?q=#{sessionScope.houseDetails.Street},
+#{sessionScope.houseDetails.City},
+#{sessionScope.houseDetails.Zip}"
text="#{sessionScope.houseDetails.Street}"/>
It is also possible to program driving directions using this feature. The format of the Google Maps URL would be:
http://maps.google.com/maps?saddr=<Start_Address>&daddr=<destination_address>
</destination_address>
This is a very powerful feature; it allows ADF and JDeveloper developers to invoke driving directions functionality with just a few lines of code. A user can simply click on a link on an ADF Mobile view to get location or driving directions through Google Maps functionality.

Conclusion

iPhone has re-defined "ease of use" for mobile devices; almost anyone can easily pick it up and use it without extensive training. The reason for that is no secret: the user interfaces of iPhone's core applications work perfectly with the device hardware. Any other application running on the iPhone will need to adhere to that user interface standard, or the user will lose the "ease of use advantage" when using that application. In thius article, you learned how easily such a user interface can be developed using Oracle ADF and JDeveloper, so any developer can rapidly create a compelling iPhone Web App today.

More Resources for Getting Started Now

The following resources will help to get started on iPhone development using ADF and JDeveloper today:


Joe Huang is the product manager for Oracle ADF Mobile.