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:
- 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.
- 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.
- 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.
To add iPhone resolution to the View Editor:
- 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
- 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" />
- 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" />
- 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.
- 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
.
- 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.

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:

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:
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=
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. |