As mobile computing continues to grow, in number of devices and in number of users of those devices, more and more mobile-only or mobile-specific websites and web applications are being developed. Keeping track of all these devices, their operating system versions, the capabilities each device has, and so on can be a daunting task. Modern mobile browsers coupled with emerging standards and technologies such as HTML5 and CSS3 are helping to make device specifics less of a worry. However, many idiosyncrasies still do and most likely always will exist among devices, and it's invaluable to have that information at your disposal.
By using the Wireless Universal Resource File (WURFL—pronounced "were-full"), however, you can fine-tune your mobile sites and applications easily, because you know exactly what the device can and cannot do. Without WURFL, this task would be challenging if not impossible.
What is the WURFL?
The WURFL is an open source Device Description Repository (DDR) project run by ScientiaMobile that aims to be an independent central repository of mobile device information. It is used by Facebook and Google as well as many other organizations both large and small. Valuable device information such as the make and version of the mobile browser being used, whether the device is a tablet, whether it can support Flash, and much more can all be found within the WURFL.
In its simplest form, the WURFL is a repository of thousands of mobile devices and their respective capabilities. The DDR consists of an XML configuration file matched with a set of APIs that allow you to retrieve a vast amount of information about a given mobile device with little effort. Using the WURFL PHP API, you can easily start using the WURFL in your mobile PHP development right away.
Exploring the WURFL
Enough talking about why to use the WURFL and what it can do: Let's explore what the data inside the WURFL looks like and what kind of information you can gather about a given device by using it.
You should familiarize yourself with the types of data found in the WURFL before you start using the DDR with the WURFL PHP API. Remember that in its simplest form the WURFL is an XML file: When you open the WURFL file, you will see all the data composed within a set of XML nodes. There are several nodes inside the WURFL file, but there are only three nodes where you will find data about a given mobile device. Table 1 shows these device nodes.
Table 1. The main WURFL device nodes
|The main node that holds information for the given device|
|Child of the device node; contains information about a defined feature|
|Child of a group node; lists the individual capabilities of a given device, specified within a given group|
From Table 1, you can determine the basic XML structure for each device:
<device> <group> <capability /> <capability /> <capability /> </group> <group> <capability /> <capability /> <capability /> </group> </device>
For example, if you look inside the WURFL, you will find the device entry shown in Listing 1 for the Apple iPhone 4.
Listing 1. iPhone 4 WURFL entry
<device id="apple_iphone_ver4" user_agent="Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Mobile/7D11" fall_back="apple_iphone_ver3_1_3" actual_device_root="true"> <group id="product_info"> <capability name="model_name" value="iPhone"/> <capability name="device_os_version" value="4.0"/> <capability name="model_extra_info" value="4.0"/> <capability name="release_date" value="2010_april"/> </group> <group id="playback"> <capability name="playback_acodec_aac" value="lc"/> <capability name="playback_mp4" value="true"/> <capability name="playback_3gpp" value="true"/> <capability name="playback_acodec_amr" value="nb"/> <capability name="playback_acodec_qcelp" value="false"/> <capability name="playback_vcodec_mpeg4_sp" value="3"/> <capability name="playback_vcodec_h263_0" value="30"/> <capability name="playback_3g2" value="true"/> <capability name="playback_vcodec_h264_bp" value="3.0"/> </group> <group id="streaming"> <capability name="streaming_vcodec_h263_0" value="30"/> <capability name="streaming_acodec_aac" value="lc"/> <capability name="streaming_3gpp" value="true"/> <capability name="streaming_vcodec_h264_bp" value="3.0"/> <capability name="streaming_acodec_amr" value="nb"/> <capability name="streaming_preferred_protocol" value="http"/> <capability name="streaming_vcodec_mpeg4_sp" value="3"/> <capability name="streaming_mp4" value="true"/> </group> </device>
From this example, you can see that there are two child group nodes inside the main device node for the iPhone 4 entry. These two nodes provide detailed information about the audio and video codecs supported on this device. But wait: Shouldn't there be more information here, such as whether the device supports Flash or PDF or if it's a tablet? Yes! You can indeed find this information in the WURFL, but because of the nature of the WURFL and how it builds on existing device information already in the repository, it's clearly not in this entry.
Because the WURFL contains thousands of device specifications multiplied by their respective capabilities, it can quickly become an increasingly complex data matrix to continue to build on and maintain. However, one of the smart things about the WURFL is how it manages this complexity.
The creators of the WURFL took the following facts about mobile devices into consideration:
- Although browsers are different, they have many features in common.
- Browsers and devices coming from the same manufacturer invariably evolve from the same hardware and software. Consider the Research in Motion BlackBerry Curve 9350, 9360, and 9370: The commonalities among them are many, and the differences are minimal.
Taking all of that into consideration allows the WURFL to be less complex and easier for the maintainers to update. In essence, the WURFL is based on a concept of a family of devices. If you look at the first device listed in the WURFL file, you will see a device with the ID generic. Everything in the WURFL file builds off of this generic device. As a new device is added that falls within a pre-existing device family, it inherits all of the capabilities of that family unless there is something specifically different for that device, at which point, the information will be added to that given device.
For example, if you look at the
fall_back attribute of the
<device> node in the iPhone 4 example in
Listing 1, you will see that it references
apple_iphone_ver3_1_3—the device ID attribute of
a previous iPhone device entry in the WURFL. If you continue to follow that ID back, you
end up with a device node with the attribute ID
Along the way, you will find additional device information, such as its preferred
geolocation API, whether it supports Adobe Flash Light, and the display resolution.
Some of the groups you will find are provided in Listing 2.
Listing 2. Device groups found in WURFL
<group id="ajax"> <capability name="ajax_preferred_geoloc_api" value="w3c_api"/> </group> <group id="display"> <capability name="resolution_height" value="480"/> <capability name="resolution_width" value="320"/> </group> <group id="flash_lite"> <capability name="flash_lite_version" value=""/> <capability name="fl_wallpaper" value="false"/> <capability name="fl_browser" value="false"/> <capability name="fl_screensaver" value="false"/> <capability name="fl_standalone" value="false"/> <capability name="fl_sub_lcd" value="false"/> </group>
As you can see from the iPhone4 WURFL entry, every specification for a
given device starts with the main
node. These nodes always contain the user-agent string attribute, a
fall_back device attribute, and a unique ID
The WURFL contains a number of data groups. These groups are child nodes
of the device node, and each defines a capability that a device may or may not
support as well as more granular details about the capability found within the
group node. The groups you will find today in the WURFL are
An up-to-date list of groups as well as a full description of each that includes a tabular breakdown of the capabilities defined within the given group (such as the capability name, type, and description) can be found in the WURFL help document (see Resources for a link).
Capabilities are defined within their parent groups. All capability name attributes are unique, even between groups, so no capability name will appear more than once within a device specification. In addition, capabilities always have a value; the value of a capability is a Boolean, a string (even an empty string), or a number.
Listing 3 provides examples of actual groups—with their defined capabilities—that you can find within the WURFL.
Listing 3. The WURFL product_info group and its capabilities
<group id="product_info"> <capability name="pointing_method" value="touchscreen"/> <capability name="uaprof" value="http://www.blackberry.net/go/mobile/ profiles/uaprof/9500_edge/4.7.0.rdf"/> <capability name="model_name" value="BlackBerry 9500"/> <capability name="brand_name" value="RIM"/> <capability name="model_extra_info" value="Thunder"/> <capability name="marketing_name" value="Storm"/> </group>
Here, you have the most commonly found group,
As you can see, you can find basic information about the device, such as the
model and brand name, as well as whether the device has a touchscreen and the
Another commonly found group is
display, shown in
Listing 4, which provides details about the device's screen
dimensions and resolution. This information is particularly helpful when you're
trying to display a mobile site or web application correctly on a given device
rather than leaving it all to guesswork.
Listing 4. Finding device screen information in the WURFL
<group id="display"> <capability name="physical_screen_height" value="66"/> <capability name="columns" value="36"/> <capability name="dual_orientation" value="true"/> <capability name="physical_screen_width" value="50"/> <capability name="max_image_width" value="340"/> <capability name="rows" value="32"/> <capability name="resolution_width" value="360"/> <capability name="resolution_height" value="480"/> <capability name="max_image_height" value="440"/> </group>
With these two groups, you can see that the device supports PDF documents (see Listing 5) as well as the Java™ 2 Platform, Mobile Edition (J2ME). Again, you can see how useful it is to have this information about the connecting device at your disposal without having to guess or spend additional time writing code to check for these features.
Listing 5. Checking PDF support for a given device
<group id="pdf"> <capability name="pdf_support" value="true"/> </group> <group id="j2me"> <capability name="j2me_midp_2_0" value="true"/> <capability name="j2me_cldc_1_0" value="true"/> <capability name="j2me_cldc_1_1" value="true"/> <capability name="j2me_midp_1_0" value="true"/> </group>
Working with the PHP API
The PHP API that the WURFL project provides makes it easy to start using the WURFL in your PHP development. (See Resources for a link to download the latest WURFL PHP API.) The following simple example shows how quickly and easily you can retrieve a capability for a given mobile device.
For this example, you use the
getCapability method to pass
in a few different capability names found within the WURFL. You retrieve the brand
and model name, the device's resolution width and height, and whether the device can
support PDFs and Flash. This example assumes that you have downloaded and extracted
the WURFL PHP API to the web server root; you can find the code in
Listing 6 within the demo directory inside the top-level WURFL PHP
Listing 6. Demo code for the PHP API example
<?php define("WURFL_DIR", dirname(__FILE__) . '/../../WURFL/'); define("RESOURCES_DIR", dirname(__FILE__) . "/../resources/"); require_once WURFL_DIR . 'Application.php'; $wurflConfigFile = RESOURCES_DIR . 'wurfl-config.xml'; // Create WURFL Configuration from an XML config file $wurflConfig = new WURFL_Configuration_XmlConfig($wurflConfigFile); // Create a WURFL Manager Factory from the WURFL Configuration $wurflManagerFactory = new WURFL_WURFLManagerFactory($wurflConfig); // Create a WURFL Manager ($wurflManager is a WURFL_WURFLManager object) $wurflManager = $wurflManagerFactory->create();
First, set up the appropriate path to the application.php file (provided with the WURFL
PHP API) as well as the WURFL XML file. Then, create the WURFL
Manager object. The calls to retrieve specific device
information are retrieved from that object.
With the WURFL
Manager object created, query the WURFL
for a few pieces of data, as shown in Listing 7.
Listing 7. Querying the WURFL for data
// This line detects the visiting device by looking at its HTTP Request ($_SERVER) $requestingDevice = $wurflManager->getDeviceForHttpRequest($_SERVER); ?> <html> <body> <ul> <li>ID: <?php echo $requestingDevice->id; ?> </li> <li>Brand Name: <?php echo $requestingDevice->getCapability("brand_name"); ?> </li> <li>Model Name: <?php echo $requestingDevice->getCapability("model_name"); ?> </li> <li>Resolution Width: <?php echo $requestingDevice->getCapability("resolution_width"); ?> </li> <li>Resolution Height: <?php echo $requestingDevice->getCapability("resolution_height"); ?> </li> <li>PDF Support: <?php echo $requestingDevice->getCapability("pdf_support"); ?> </li> <li>Flash Support: <?php echo $requestingDevice->getCapability("full_flash_support"); ?> </li> </ul> </body> </html>
When I load this page on my iPhone 4, I see the device ID, its make and model, screen information, and whether it supports PDF and Flash. Figure 1 shows the results.
Figure 1. Results of the example code on iPhone 4
From this example, you can see that retrieving the value of a capability for a device is
as simple as calling the
getCapability method with the
appropriate capability name.
From this article, you can see that there's a lot of value in using the WURFL in your mobile site or application. Quickly and easily gathering information about a given device rather than investing hours of additional programming time and many additional lines of code for data that could otherwise have been impossible to retrieve is by far the most attractive part of this powerful DDR.
Part 2 of this article series will dig into the WURFL PHP API in more depth and provide examples of how you can put it to use in your mobile PHP development.
- Learn more at the WURFL project page and WURFL help documentation.
- Read more about the PHP API in the WURFL PHP API documentation.
- If you discover a device that's not in the WURFL, you can contribute device information to the DDR.
- The Open source zone on developerWorks provides a wealth of how-to information on open source tools and technologies.
- Check for mobile updates on the developerWorks Mobile development blog.
- You'll find many more articles on mobile topics, including articles on Dojo Mobile on developerWorks.
- Stay current with developerWorks technical events and webcasts focused on a variety of IBM products and IT industry topics.
- Attend a free developerWorks Live! briefing to get up-to-speed quickly on IBM products and tools, as well as IT industry trends.
- Watch developerWorks on-demand demos ranging from product installation and setup demos for beginners, to advanced functionality for experienced developers.
- Follow developerWorks on Twitter.
Get products and technologies
- Download the latest WURFL repository.
- Download the latest WURFL PHP API.
- Download and try the IBM Mobile Technology Preview, a set of code samples and services to help you get started building mobile applications that extend and integrate into the enterprise. The preview includes a RESTful notification service; PhoneGap, an open source framework for building hybrid mobile apps; a lightweight WebSphere Application Server runtime; and sample code to let you see how it all works.
- IBM WebSphere Application Server Feature Pack for Web 2.0 and Mobile includes the IBM Dojo 1.7 Toolkit, new mobile and rich Internet application (RIA) building blocks, and a Dojo-based diagram component. With accompanying Rational tools, the Feature Pack helps you take WebSphere applications developed originally for desktop browsers and adapt and deploy them to mobile devices.
- Evaluate IBM products in the way that suits you best: Download a product trial, try a product online, use a product in a cloud environment, or spend a few hours in the SOA Sandbox learning how to implement Service Oriented Architecture efficiently.
- Get involved in the developerWorks community. Connect with other developerWorks users while exploring the developer-driven blogs, forums, groups, and wikis.