Many people today associate mobile development with the development of an application for the iPhone, Android, or Windows Phone 7. Mobile development, though, certainly did not originate with iPhone. As early as a decade ago, Wireless Application Protocol (WAP) and Wireless Markup Language (WML) emerged as the respective counterparts of HTTP and HTML for mobile browsers. The first version of ASP.NET also included a special namespace for server controls to enable you to write mobile sites using the same developer experience as for regular ASP.NET-based websites. For some reasons (mostly lack of ubiquitous Wi-Fi connectivity and non-flat data rates), the WAP/WML duo, and with it development of mobile websites, never really caught on.
After a decade of waiting, today we are witnessing the definitive explosion of mobile computing. The technological scenario is a bit different, though. WML has been replaced by XHTML, and a bunch of newer mobile operating systems (iOS, Android, Windows Phone 7, Symbian, BlackBerry) have evolved along with smarter phones equipped with better hardware and overall much better usability. These new mobile OSs are drawing a lot of attention from developers. It is common these days to run across endless threads about the (false) dichotomy between native mobile applications and mobile sites. Mobile native applications and mobile websites are much more complementary than many seem to think. And mobile sites still keep customers no more than a URL away from the company's site.
If your business's mobile strategy includes building a mobile website, there's a technology you need to know about: Wireless Universal Resource File (WURFL), a database of information about mobile devices and browsers. I will introduce WURFL and explain how you can integrate it into your ASP.NET applications to support mobile websites. But before that, let's back up a bit and look at some higher-level considerations related to mobile strategy.
What's a Mobile Strategy, Anyway?
A company's mobile strategy depends on its business model. In a business-to-consumer scenario, some companies may need to push out an array of applications to cover the major families of smartphones. This typically happens when applications have high value for a relatively small group of loyal users.
Other companies, instead, may want to be reachable by as many people as possible over all possible mobile devices. For those companies, a device-optimized mobile website is the obvious solution. Of course, companies can adopt both solutions and offer a mobile site to everyone while encouraging customers to download a specific application for a particular smartphone.
In a business-to-business scenario, in addition to the strategies I just mentioned, some companies may opt to choose one mobile platform and tailor their mobile website and application development to that platform.
The Multi-Serving Approach and WURFL
When it comes to mobile site development, you must take into account thousands of different models of devices, not just a few dozen models of smartphones, often with a prefixed set of capabilities. How would you approach this challenging task?
Writing a set of pages (if not the entire website) per device model is simply not feasible. The one-size-fits-all approach is viable, but it comes at the cost of leaving a lot of legacy devices behind and relinquishing the advanced features of smartphones. This is typically not good enough for companies that found their success with online content, such as social networks or media and news companies.
The alternative is multi-serving, which basically consists of three points: Group devices in classes based on capabilities, build a version of the site per classes you intend to support, and define a strategy to serve the right site to each device that connects to the site.
Multi-serving takes mobile development to a new level of complexity, but it is here where WURFL shows its value: As emphatic as it may sound, WURFL makes multi-serving manageable. Multi-serving is expensive per se; with WURFL it becomes a lot less expensive.
WURFL is a centralized database that stores detailed information about thousands of mobile devices and browsers. The main point of the WURFL framework is that it shifts the focus from devices' brand and model to mobile browser capabilities. A mobile site built to accommodate the effective capabilities of the mobile browser installed on, or embedded in, a given device is much more resilient and also self-updating. Any device and browser updates are promptly incorporated into the WURFL database and simply result in a different mapping between the requesting client and version of the site to serve.
This approach, devised by Luca Passani more than 10 years ago, has proved so successful that pretty much any commercial mobile solution developed since then has adopted it.
Fighting Device Fragmentation
But stop for a moment and think about what jQuery really does. It basically branches out when it is about to perform some action that is "known" to require some specific browser capabilities. If jQuery can't detect the capability, then it degrades as gracefully as possible. The term device fragmentation refers to the large number of different configurations (i.e., features and capabilities) that you can find among mobile devices.
Can a client-side library be used to address mobile device fragmentation as effectively as it can do for desktop browser fragmentation? Yes, but only partially.
For example, how would you programmatically detect whether the data URI scheme is supported (that is, it's able to embed image files as Base64 encoded text)? How would you find out that, say, touch events are technically supported but too slow to be really usable on the device? In this case, you'd better ignore the capability and resort to a simpler but more comfortable user experience. What if a browser has a bug (or feature…) that causes it to ignore "width:100%" thus wrapping tables around cell content? What if the browser is not precise (actually, lies) about the real width and height of the screen? These are the real issues that mobile developers encounter every day. It's unlikely that standard jQuery or even jQuery Mobile can be of significant help in all cases. Unsurprisingly, the team behind jQuery Mobile seems to be very aware of this as they push out a detailed list of operating systems and browsers they support in various grades. (Here's the full story.)
In a nutshell, only a few capabilities can be effectively detected automatically by some client- and/or server-side code. In general, human recognition and judgment is the most reliable approach.
The Browser Capabilities Oracle
For years, ASP.NET developers used a built-in object to query for (just a few basic) browser capabilities. The Request object exposes the Browser property, which in turn points to an HttpBrowserCapabilities object. This object offers about 100 properties describing what the browser can or cannot do. The ASP.NET infrastructure detects the user agent string (UAS) and in some way maps that to the closest entry in an internal database of known browser capabilities. Data that's read is then loaded into the Browser property and made available to developers. The idea behind the model is just right; the actual implementation is largely insufficient even for moderately complex scenarios.
In ASP.NET, browser capabilities are stored in XML files, and you can add more XML files to cover more devices and mobile browsers. The default list, however, contains about 10 browsers. This is good for desktop scenarios but patently insufficient for mobile scenarios. The work required to extend the list is huge and, worse yet, entirely on the development team's shoulders. Another key limitation is the expressivity of the model that renders out capabilities: 100 capabilities are not enough, and the model itself is quite old as it lacks valuable information, such as whether the device is a tablet or whether images can be embedded with the markup.
Also, this model is highly dynamic by nature and requires a much more flexible infrastructure that can effectively catalog new browsers and devices as they hit the market.
The fundamental point of mobile development is to set up an independent authority that can serve up-to-date and trusted information about nearly any mobile browser. The information has to be organized in macro families of browser capabilities so that each UAS can be promptly associated with a known set of capabilities. And any new UAS can be quickly added or moved to the right place. Finally, the set of capabilities needs to be much more granular and detailed than in ASP.NET.
WURFL is a community-powered project that qualifies to be the oracle that tells you all the truth about the mobile browser that is viewing your page. WURFL is an XML database that today includes more than 7,000 UASs and more than 500 capabilities. The home page of the WURFL project is wurfl.sourceforge.net. WURFL is the driving force behind the exceptional capabilities of the Facebook mobile site. (Read the full story atgoo.gl/nv1JW and goo.gl/5i6lK.)
A Quick Look at the WURFL Repository
The WURFL database is an XML file that, compressed, measures about 1MB. It basically consists of a flat list of <device> elements. Figure 1 shows the overall skeleton of the database.
<devices> <device id="..." user_agent="..." fall_back="..."> <group id="..."> <capability name="..." value="..." /> : </group> : <device> : </devices>
The key attribute here is fall_back. The attribute refers by name to other <device> elements. The fall_back attribute indicates the device from which missing capabilities of the present device will be inherited. Each device section describes just the delta between that device and its parent device. The user_agent attribute indicates a specific user agent string to be matched. Capabilities are split into groups such as xhtml_ui, markup, ajax, display, sms, and others. Each capability has name and value; the value is always rendered as a string. The code excerpt in Figure 2 illustrates the CSS capabilities of the generic device-the root of WURFL devices. How would you consume this huge amount of information (unzipped, the latest WURFL file reaches 15MB)?
<group id="css"> <capability name="css_gradient" value="none" /> <capability name="css_border_image" value="none" /> <capability name="css_rounded_corners" value="none" /> <capability name="css_spriting" value="false" /> <capability name="css_supports_width_as_percentage" value="true" /> </group>
Integrating WURFL in Applications
The great news about WURFL is that you don't have to write your own XML parser in order to query information. Familiarity with the WURFL XML schema is useful because it allows you to manually add device information should you ever need to, but it is not strictly required for programming purposes. The WURFL project, in fact, offers three official APIs: for Java, .NET, and PHP.
The word "official" here means that the same team that collects and exposes the data also takes care of delivering and maintaining the APIs. This is really an important point as it guarantees detection accuracy and optimal performance and keeps you automatically up to date should significant changes to the schema become necessary. Because the API is an integral part of the project, changes to the structure of data are automatically reflected by the API.
However, the WURFL data is publicly available on the project's site, and anyone can download the data and write an alternative API. I tried that route myself with the excuse that I needed to check just a subset of the available information. I realized quite soon, however, that I was having a few false positives and that, more importantly, it was out of my control. So I switched to the official API. Figure 3 shows what it takes to integrate the WURFL API in an ASP.NET application.
var configurer = new InMemoryConfigurer() .MainFile(Path(_wurflDataFile)) .PatchFile(Path(_wurflPatchFile)); var wurflManager = WURFLManagerBuilder.Build(configurer); if (wurflManager == null) throw new ArgumentNullException("Null reference to WURFL manager."); Cache["WurflManager"] = wurflManager;
You place the code from Figure 3 in the global.asax file. After that, you retrieve the WURFL manager from the cache and query for the data you need, like this:
var device = wurflManager.GetDeviceForRequest(userAgent); var capsDictionary = device.GetCapabilities(); if (capsDictionary["is_tablet"]) ...
Capabilities are exposed through a name/value dictionary. You can find the names of the more than 500 capabilities in theWURFL documentation.
An Essential Mobile Dev Tool
Website developers need to be able to do a couple of basic things: Detect whether the browser is a mobile browser and get detailed information about the browser's actual capabilities. In very simple cases, this can be done through the ASP.NET browser infrastructure. But if you need to optimize pages on the server side for a few classes of mobile browsers, then WURFL is the only option you have, providing a native API that lets you integrate WURFL into your ASP.NET applications.