by Dino Esposito, our WURFL Developer Evangelist for Microsoft Technologies and .NET Guru
The WURFL platform has supported virtual capabilities in its WURFL Cloud service for a while. Now, with the release of the API 1.5, virtual capabilities have been revised and extended to the WURFL OnSite, WURFL InFuze and WURFL InSight frameworks. In this post, we discuss virtual capabilities and how to use them in .NET applications.
In general, there are some capabilities that are easy and straightforward to associate with a value, and other capabilities that require some calculation and depend on the value of other capabilities. For example, it’s fairly easy and unambiguous to determine whether a device is a tablet or a smart TV; it’s much less obvious to define what a smartphone is.
In WURFL, a virtual capability is a capability whose value results from some elaboration done on top of one or more other capabilities. Getting even closer to the structure of WURFL, we could say that a virtual capability is not physically stored in the WURFL database, but is computed on demand. Conceptually, a virtual capability can be assigned to a computed column in a relational database. Beyond this point, though, a virtual capability is exactly the same as a regular capability and is used in the same way.
The table below lists the virtual capabilities supported in the WURFL API 1.5.
|is_smartphone||Indicates whether the device is reckoned to be a smartphone. Internally, the matcher checks the operating system, screen width, touch and a few other capabilities.|
|is_ios||Indicates whether the device runs iOS (any version).|
|is_android||Indicates whether the device runs Android (any version).|
|is_app||Indicates whether you’re getting the request through the browser embedded in a native app. This typically happens if the web page is hosted in a WebView component.|
|is_robot||Indicates whether the device is reckoned to be a robot.|
|advertised_device_os||Returns the common name of the operating system mounted on the device.|
|advertised_device_os_version||Returns the version of the operating system mounted on the device.|
|advertised_browser||Returns the common name of the default browser mounted on the device.|
|advertised_ browser _version||Returns the version of the default browser mounted on the device.|
ike standard capabilities, virtual capabilities also always return a string value. Boolean virtual capabilities, for example, return either “true” or “false”. Virtual capabilities in the “advertised” group, instead, just return a string that gives the commercial and familiar name/version of the underlying operating system and default browser available on the device. Most of the time, the value of the device_os standard capability coincides with the value returned by advertised_device_os. The difference is in an extra layer of normalization that is applied after reading the value of the standard capability.
You query for a virtual capability using the following code:
var gotSmartphone = device.GetVirtualCapability("is_smartphone");
In WURFL 1.5, the GetVirtualCapability method has been added to the IDevice public interface along with the GetVirtualCapabilities method if you prefer to retrieve all virtual capabilities in a single shot. Below is the signature of both methods:
String GetVirtualCapability(String name); IDictionary<String, String> GetVirtualCapabilities();
Internally, virtual capabilities rely on a separate set of matchers and abstraction layer that provides caching and overriding through patch files.
One thing we’ve learned over the years is that there are capabilities whose value once established in the WURFL database are generally good for everyone. On the other hand, is quite difficult to argue against a given device being wireless or not. However, not all capabilities are the same and it makes totally sense that you ask for a tool to override values set in the database. We provide patch files for that. And patch files have been a standard capability since the beginning of WURFL. Nicely enough, we extended the mechanism of patch files to virtual capabilities too.
You can override the default returned value for a virtual capability using a matching control_cap property in your patch file. For example, let’s say that for a given device WURFL sets the is_smartphone virtual capability to “true.” Let’s also say that for your application it would be better to treat that device as a plain phone. All you do is adding a controlcap_is_smartphone property to the patch file for the given device and assign it any of the following values: force_true or force_false. Here’s a fragment from a sample patch file where the is_smartphone capability is overridden to false.
<group id="virtual"> <capability name="controlcap_is_app" value="default" /> <capability name="controlcap_is_robot" value="default" /> <capability name="controlcap_is_ios" value="default" /> <capability name="controlcap_advertised_device_os_version" value="default" /> <capability name="controlcap_is_android" value="default"/> <capability name="controlcap_advertised_browser_version" value="default" /> <capability name="controlcap_advertised_browser" value="default"/> <capability name="controlcap_is_smartphone" value="force_false" /> <capability name="controlcap_advertised_device_os" value="default" /> </group>
With virtual capabilities, arranging multi-device solutions is easier – especially in ASP.NET MVC. In a nutshell, you can leverage display modes of ASP.NET MVC 4 (and newer) and use a mix of standard and virtual capabilities (is_tablet, is_smartphone, is_smarttv) to easily add display conditions to your site. But this is close to becoming a completely different topic worthy of another post. Meanwhile, here’s a link to an MSDN Magazine article that talks ASP.NET MVC and WURFL together. It doesn’t mention API 1.5 and virtual capabilities, but you can easily see where virtual capabilities fit in.