Think Generic

Sometimes, thinking in generic terms, instead of specific cases/problems, pays off later with greater benefits. I'm going to show you a small real world example.

When you develop a mobile website, you usually create at least two visual themes, and usually go up to three:

  1. WML layer: Limited, almost text only, and very crappy because of the limitations of the devices requesting this version of the site.
  2. XHTML layer, low/med-end capabilities: Devices that can render XHTML, some CSS, etcetera, but have small resolutions or some other problems (like no javascript, or a terrible CSS implementation, like PocketIE).
  3. "Full" browsers: mostly WebKit and Opera for mobile devices. Capable of standard javascript, really good resolutions (and zoom), can run almost perfectly any website, just with a lower resolution than a computer.

If your website is properly developed, all the "mobile versions" will have a common logic layer and data layer (or if it's an MVC, common Models and Controllers), so it's just a matter of detecting what version the visitor falls into and rendering the appropiate view(s).

For WML is quite easy with the HTTP Accepts header, but with the more capable devices, we usually rely on checking the HTTP User Agent header.

As an example, this is an iPhone with 3.0 OS user agent string:

Mozilla/5.0 (iPhone; U; CPU like Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3

For an iPod Touch is almost the same, just changing the "iPhone" with an "iPod".

At first glance, a small regular expression to detect the words iPhone and iPod would solve the problem, no?

Well, it does, but not in a generic scope. Let's see now how an Android user agent looks:

Mozilla/5.0 (Linux; U; Android 1.5; en; HTC Magic) AppleWebKit/528+ (KHTML, like Gecko) Version/3.1.2 Mobile Safari/525.20

Using the proposed approach we would have to add "Android" to the "nice devices" list, but until then we would be rendering on all Androids the less fancy XHTML version.

But the alternative, is to search inside the user agent for two words, "Mobile" + "Safari" (order matters!). If you look at both user agents, they both are WebKit implementations, so both are Mobile Safari browsers. Using this second approach we already support all present and future Android devices without changing our code. In fact, we will support any new browser based on Mobile Safari!

So the lesson here is to try to go for a generic approach. In this example, targeting for browser type instead of specific device id gives a lot more flexibility with the same effort and even lowers the need of modifying the code in the future.

Tags: Development Patterns & Practices

Think Generic article, written by Kartones. Published on