Low brow iPhone users and Divergence

28 01 2009

On the topic of detecting capabilities of specific devices – here’s a new site we’ve released that targets the growing segment of “low brow” iPhone users (which includes me).

http://iDidntDoThat.com

It’s a simple prank tool along the lines of iFart – however it let’s you turn your iPhone into a remote control for your friend’s and family’s computers. You just load a webpage on their PC when they’re not looking and then you can use your iPhone to make it sound like they’re burping, farting or even watching porn. And you don’t have to leave your precious and expensive iPhone lying around on someone else’s desk to play this prank!

We’ll be upgrading the site to support other mobile devices soon…however we decided to quickly release the first version just for iPhone users as it’s so much easier to deliver a better user experience. We’ve also developed it as an iPhone application that will be released as soon as the AppStore team approve it.

But underlying this “low brow” toy is the deeper “high brow” concept of Divergence. I think a lot of people find this concept a little academic, however http://iDidntDoThat.com is a fun way of showing exactly what it means and feels like.

We use this same framework to connect all sorts of devices and applications across the network. We can make your phone or PC chirp whenever someone visits your site or just play a “cha ching” when it processes a sale. The same framework can even let call centre staff shift their focus from “filling in forms” and “reading out disclaimers” to a much friendlier and more brand-building “co-browsing” with your customers, helping guide them through your site to find the best matched product or solution for them.

Once you detach user interfaces from specific devices or applications and really start to absorb what Divergence means I think you’ll agree it opens up a whole new range of business models and opportunities.





Not-Device Detection javascript, perl and php code

26 01 2009

While server based detection using mod_rewrite or similar will provide a much better level of performance, sometimes you just want to handle it from within a script. Below are examples in javascript, perl and php so you can choose your language/environment. I would strongly recommend using a server side script (e.g. perl or php) but I’ve included a javascript version for reference. Of course if you’re cutting edge then you could run the javascript on the server-side too.

I hope you find this code useful. If you find any bugs or logical errors please let me know.

NOTE: This code is designed to support 3 key classes of device – PC, iPhone and POM (Plain Old Mobile). See the comments by the winmo detection that shows where you may like to extend this for other high-end devices (e.g. Windows Mobile or Symbian).

Javascript Example:

/**
 *  Copyright © 2009
 *  Rob Manson, Sean McCarthy and http://MOBusiness.com.au
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 *
 *  Javascript Not-Device Detection Function
 *  Find out what type of device this is
 *  returns string - either pc, pom or iphone
 */
function _not_device_detection() {
    var ua = navigator.userAgent;
    var qs = window.location.search.substring(1);
    var agent = "error";
    var re = {
        "pcswitch" : new RegExp("pc", "i"),
        "pomswitch" : new RegExp("pom", "i"),
        "iphoneswitch" : new RegExp("iphone", "i"),
        "iphone" : new RegExp("iP(hone|od)(;|\s)", "i"),
        "winmo" : new RegExp("Windows\s+CE", "i"),
        "linux" : new RegExp("Linux", "i"),
        "windows" : new RegExp("Windows", "i"),
        "mac" : new RegExp("OS\s+(X|9)", "i"),
        "solaris" : new RegExp("Solaris", "i"),
        "bsd" : new RegExp("BSD", "i")
    };
    if (qs.match(re.pcswitch)) {
        /* This assumes you have a single query string value of "pc" */
        agent = "pc";
    } else if (qs.match(re.pomswitch)) {
        /* This assumes you have a single query string value of "pom" */
        agent = "pom";
    } else if (qs.match(re.iphoneswitch)) {
        /* This assumes you have a single query string value of "iphone" */
        agent = "iphone";
    } else if (ua.match(re.iphone)) {
        /* This user agent should be an iPhone/iPod */
        agent = "iphone";
    } else if (ua.match(re.winmo)) {
        /* This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too */
        agent = "pom";
    } else if (
        (!ua.match(re.linux)) &&
        (!ua.match(re.windows)) &&
        (!ua.match(re.mac)) &&
        (!ua.match(re.solaris)) &&
        (!ua.match(re.bsd))
    ) {
        /* This user agent is not Linux, Windows, a Mac, Solaris or BSD */
        agent = "pom";
    } else {
        /* Otherwise assume it's a PC */
        agent = "pc";
    }
    return agent;
}

Perl Example:

######################################################################################################
##  Copyright © 2009
##  Rob Manson, Sean McCarthy and http://MOBusiness.com.au
##
##  This program is free software: you can redistribute it and/or modify
##  it under the terms of the GNU General Public License as published by
##  the Free Software Foundation, either version 3 of the License, or
##  (at your option) any later version.
##
##  This program is distributed in the hope that it will be useful,
##  but WITHOUT ANY WARRANTY; without even the implied warranty of
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##  GNU General Public License for more details.
##
##  You should have received a copy of the GNU General Public License
##  along with this program.  If not, see .

##
## Perl Not-Device Detection method 
## Find out what type of device this is
## returns string - either pc, pom or iphone
######################################################################################################
sub _not_device_detection() {
    # either pass in \%ENV or pack the UA and QUERY into a hashref and pass that in
    my $env = shift;
    my $ua = $env->{HTTP_USER_AGENT};
    my $qs = $env->{QUERY_STRING};
    my $agent = "error";
    if ($qs =~ /^pc$/i) {
        # This assumes you have a single query string value of "pc"
        $agent = "pc";
    } elsif ($qs =~ /^pom$/i) {
        # This assumes you have a single query string value of "pom"
        $agent = "pom";
    } elsif ($qs =~ /^iphone$/i) {
        # This assumes you have a single query string value of "iphone"
        $agent = "iphone";
    } elsif ($ua =~ /iP(hone|od)(;|\s)/i) {
        # This user agent should be an iPhone/iPod 
        $agent = "iphone";
    } elsif ($ua =~ /Windows\s+CE/i) {
        # This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too
        $agent = "pom";
    } elsif (
        (!$ua =~ /Linux/i) &&
        (!$ua =~ /Win/i) &&
        (!$ua =~ /OS\s+(X|9)/i) &&
        (!$ua =~ /Solaris/i) &&
        (!$ua =~ /BSD/i)
    ) {
        # This user agent is not Linux, Windows, a Mac, Solaris or BSD 
        $agent = "pom";
    } else {
        # Otherwise assume it's a PC
        $agent = "pc";
    }
    return $agent;
}

PHP Example:

/**
 *  Copyright © 2009
 *  Rob Manson, Sean McCarthy and http://MOBusiness.com.au
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see .
 * 
 * PHP Not-Device Detection Function
 * Find out what type of device this is
 * returns string - either pc, pom or iphone
 */
function _not_device_detection() {
    $ua = $_SERVER['HTTP_USER_AGENT'];
    $qs = $_SERVER['QUERY_STRING'];
    $agent = "error";
    if (preg_match('/^pc$/i', $qs)) {
        /* This assumes you have a single query string value of "pc" */
        $agent = "pc";
    } else if (preg_match('/^pom$/i', $qs)) {
        /* This assumes you have a single query string value of "pom" */
        $agent = "pom";
    } else if (preg_match('/^iphone$/i', $qs)) {
        /* This assumes you have a single query string value of "iphone" */
        $agent = "iphone";
    } else if (preg_match('/.*iP(hone|od)(;|\s).*$/i', $ua)) {
        /* This user agent should be an iPhone/iPod */
        $agent = "iphone";
    } else if (preg_match('/Windows\s+CE/i', $ua)) {
        /* This user agent should be a Windows Mobile device - you may want a special class for this and possibly high-end Symbian too */
        $agent = "pom";
    } else if (
        (!preg_match('/Linux/i', $ua)) and
        (!preg_match('/Win/i', $ua)) and
        (!preg_match('/OS\s+(X|9)/i', $ua)) and
        (!preg_match('/Solaris/i', $ua)) and
        (!preg_match('/BSD/i', $ua))
    ) {
        /* This user agent is not Linux, Windows, a Mac, Solaris or BSD */
        $agent = "pom";
    } else {
        /* Otherwise assume it's a PC */
        $agent = "pc";
    }
    return $agent;
}





Not-Device Detection Example Code

25 01 2009

Well I guess it wasn’t “just” after xmas – been a bit busy enjoying the Australian summer!

We’ve had a lot of interest in the “Not-Device Detection” solution and lots of requests for example code so here it is.

Below is an example snippet from an httpd.conf (e.g. configuration for Apache) using mod_rewrite.  This assumes you have 3 main version of your homepage.

  1. An iPhone/iPod Touch version using /iphone/index.html
  2. A Plain Old Mobile (POM) version using /pom/index.html
  3. A standard PC version using /index.html

Of course you can apply this model to more sophisticated solutions that also single out other specific devices or more complex collections of sub-pages. Other examples of this could also be implemented using perl or php scripts, but the performance is much better at the web server configuration level.

So, for this example let’s step through the code.

First make sure you have the RewriteEngine switched “on”.
RewriteEngine   on
Then detect the iPhone/iPod Touch first since they’re so easy to identify.
# iPhone/iPod redirected to iPhone index
RewriteCond %{HTTP_USER_AGENT}  ^.*iP(hone|od)(;|\s).*$
RewriteRule     ^/$         /iphone/index.html [PT]

The line below allows a user to choose to view the PC version by adding ?pc to the URL (e.g. from a specific switcher icon)
RewriteCond %{QUERY_STRING}     !^pc$ [NC]
You may want to exclude a number of standard bots here using generic strings.
You may also want to add exclusions for specific monitoring tools etc.  here too
RewriteCond %{HTTP_USER_AGENT} !(spider|crawl|slurp|bot) [NC]
Then here’s the meat of the “Not-Device Detection” solution.  You’ll notice that it mostly consists of !^ statements that say if this browser is NOT Linux, NOT Windows (excluding Win CE), NOT OS X or OS 9, NOT Solaris and NOT BSD then we’ll assume it’s a Mobile Phone and redirect it to /pom/index.html.
# Plain Old Mobile (POM) redirection (by exclusion)
RewriteCond %{HTTP_USER_AGENT}  !^.*Linux.*$ [NC]
RewriteCond %{HTTP_USER_AGENT}  !^.*Win.*$ [NC,OR]
RewriteCond %{HTTP_USER_AGENT}  ^.*Windows\s+CE.*$ [NC]
RewriteCond %{HTTP_USER_AGENT}  !^.*OS\s+(X|9).*$ [NC]
RewriteCond %{HTTP_USER_AGENT}  !^.*Solaris.*$ [NC]
RewriteCond %{HTTP_USER_AGENT}  !^.*BSD.*$
RewriteRule     ^/$         /pom/index.html [PT]

Otherwise it should just receive /index.html as normal.

While this may look a little complex if you’re not comfortable reading regular expressions…I think you’ll agree it’s extremely simple when you compare it to this spaghetti diagram over on the .mobi forum.

I’d like to thank James for creating this work of art…now whenever I want to explain to a client why having a .mobi domain is a wrong headed and silly idea that makes your web strategy more complicated I just point them to this single diagram.

Anyway, I hope you find the example configuration described above useful. If you have any questions or would like any help implementing this please post a comment here.








Follow

Get every new post delivered to your Inbox.