Category Archives: Geen categorie

PhoneGap US Day 2013: Moving Forward

The first day of the PhoneGap Conference 2013 (Portland, OR) was really good. In this article I will briefly touch upon what was presented (follow the links to the presenters sites for more info on that) and then elaborate on how I see the technology can be taken to the next level, with a focus on enterprise contexts.

I am not going to say anything about the technology side of things, like OS support. There is a lot of discussion and interest in that area already.

PhoneGap Conference Day One

The first day (July 18, 2013) I attended presentations by:

  • Andy Trice, on basics, deployment to devices, debugging, etc.
  • Christophe Coenraets, on designing your PhoneGap application properly (with 10 11 architecture principles)
  • Holly Schinsky, on integration of your PhoneGap with native code for the device.

The day was both inspirational and informative, and it was good to meet a lot of people that are on the edge of technology.

Infancy Challenges

It seems Adobe PhoneGap (or it’s open source mother project Apache Cordova) is very much in it’s infancy. Integrating these technologies in enterprise projects without any on-site support is going to provide some challenges:

  1. Documentation: At first sight there is quite a lot of documentation. But for someone getting started, it is difficult to get a consistent answer on some initial questions, like:
    • What is the difference between Corova and PhoneGap? And what about Icenium?
    • How do I install this stuff on my machine? Should I download a ZIP, do ‘git clone’ or use ‘npm install’?
    • What kind of directory structure am I supposed to use?
    • How do I set myself up for debugging and profiling?
    • How do i add a plugin to my project, in a way that I support local compilation, PhoneGap Build and perhaps even Icenium?
  2. Inconsistencies in approaches: Even if you manage to get the information you need to get started, you will find there are different approaches for critical things like the directory structure:
    • If you use the (OS-specific) ‘create’ command, then you will get an OS-specific project. However, if you use the (improved, but less known) ‘cordova create’ command, then you get a completely different structure, with a project that supports multiple OSes from one directory hierarchy. Potentially there is also a ‘phonegap create’ command which might work in a similar way.
    • The ‘cordova emulate’ command runs your application in an emulator, but the ‘phonegap’ command does not have an explicit command for that, but you can run ‘phonegap run’, which will start the emulator only if there is no connected device available.
  3. Separation of concerns: In enterprise projects, it is common practice is to store the team’s files in a version control system such as Subversion or Git, and to store only the files in there that the team has authored, not the generated files.
    However, with Cordova/PhoneGap you get a whole hierarchy of generated files. And it seems that you cannot avoid editing files in that hierarchy or adding new ones, for things like registering custom plugins, adding custom splash screens and icons, etc.
  4. Integration with enterprise tools: As it currently stands, integration with common enterprise tools like e.g. Maven and Jenkins seems possible, but appears to require quite a lot of manual labor. There seem to be no Maven plugins available on the Central Repository and there might be some manual steps involved in building iOS apps.

Potential for Efficiency Improvements

On top of these challenges, I see a lot of potential for making people more efficient in creating PhoneGap applications.

A good first step was that all three presenters shared some example projects with useful (working!) code, all on GitHub:

Again, that is a good start, that can be improved upon by:

  • having official examples with a consistent approach,
  • make these examples more prominent,
  • tackle a number of things that most people will want to address in their projects anyway, like single page applications, page animations, addressing the click delay on touch devices, theming, etc.

Moving It Forward

Combining all the above, here is a non-exhaustive list of things that could be done to move Cordova/PhoneGap forward:

  1. Have a single and prominent set of interconnected tutorials on the site that answers FAQs, and guides people all the way from installing PhoneGap on their specific platform to running an example application on their emulator or device.
  2. Have a deprecation warning banner on documentation pages that pertain to older versions of PhoneGap, with a link to the latest version.
  3. Have a consistent CLI across PhoneGap and Cordova, with the PhoneGap variant only adding additional commands and features.
  4. Explicitly document and deprecate old directory structures and the old OS-specific ‘create’ command in favor of a new ‘cordova create’ or ‘phonegap create’.
  5. Standardize on a directory structure that separates authored from generated files. To comply with the Maven Standard Directory Layout, it could be set up as follows:
    • src/ – contains all authored (source) files
      • src/main/www/ – the shared PhoneGap ‘www’ directory
      • src/main/platform/ios/ – the files to merge into the iOS project, including icons, splash screens, plugin definitions, etc.
    • target/ – contains all generated files
  6. Design and implement a strategy for upgrading Cordova/PhoneGap versions, allowing people to keep their projects untouched.
  7. Make sure people do not have to touch any generated files, allowing them to run something like ‘cordova platform remove ios && cordova platform add ios’ without losing any information.
  8. Implement a Maven plugin that supports creating assets and integrates with PhoneGap Build.
  9. Implement a Jenkins plugin for integration with PhoneGap Build.

If you have any feedback, do let me know in the comments or on Twitter: @ernstdehaan.

1 Comment

Posted by on 19 July 2013 in Geen categorie


Tags: ,

Released: uasniffer 1.1

The uasniffer library just got upgraded to 1.1. Highlights of the new release:

  1. Now detecting Kindle Fire, PlayStation Portable and Opera Tablets.
  2. Improved detection of Nook e-readers.

With uasniffer you get a Java-based library that detects a wide range of devices, OSes, browsers and browser engines:

  • common browsers: MSIE, Firefox, Safari, Chrome, Opera, etc.
  • e-readers, e.g. including the Nook, Kindle, Kindle Fire, etc.
  • all iOS devices (iPod Touch, iPhone, iPad)
  • Microsoft Windows (3.1, 95, 98, ME, 2000, XP, 7, 8, etc.)
  • MacOS (up until Mountain Lion)
  • Linux, including Android variants
  • less common OSes: AIX, FreeBSD, HPUX, IRIX, BeOS, etc.
  • Firefox (from early Phoenix prototypes up until 15+)
  • Blackberry devices
  • Symbian devices (e.g. Nokia and Samsung phones)
  • Sony PlayStation (PSP) devices, including the Vita
  • less common browsers: Epiphany, Maxthon, Flock, Camino, Konqueror, OmniWeb, Dolphin, etc.
  • old browsers: NCSA Mosaic, Netscape 1+, MSIE 2+, etc.
  • mobile and mini variants, e.g. Opera Mini, Fennec, IE Mobile, etc.
  • bots, such as Pingdom and the Google Bot

To use uasniffer in your Maven-based project, declare the following dependency:


Then in your Java code analyze a specific agent string as follows:

UserAgent ua = Sniffer.analyze(agentString);

To output the detected names for inclusion in an HTML class attribute, use the getNamesAsString() method:

String allNames = ua.getNamesAsString();

E.g. for an Amazon Kindle 3 the output will be something like this:

Leave a comment

Posted by on 25 August 2012 in Geen categorie


Clean CSS with Server-Side Browser Detection (2/2)

In the first article of this duo I explained the use case for server-side browser detection. In this second post I will give a practical example, including some sample Java, HTML and CSS code.

Practical Use Case

Let’s create a simple download page with three variants:

  • an EXE file for Windows users;
  • a DMG file for Mac OS X users;
  • and a TAR GZ file for Linux users.

When the operating system of the visitor is either of these three, then the appropriate download should be highlighted.

Here’s what the result HTML5 should resemble:

<!doctype html>
<html lang="en" class="BrowserOS-Windows">
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
    <ul class="DownloadLinks">
      <li><a class="Windows" href="/install.exe">Windows installer (EXE)</a></li>
      <li><a class="Mac"     href="/install.dmg">Mac OS X installer (DMG)</a></li>
      <li><a class="Linux"   href="/install.tgz">Linux installer (TAR GZ)</a></li>

Then this is the CSS:

body {background:white;}
h1 {color:green;}

.DownloadLinks a {border:1px solid white;}

.BrowserOS-Windows .DownloadLinks a.Windows,
.BrowserOS-MacOS   .DownloadLinks a.Mac,
.BrowserOS-Linux   .DownloadLinks a.Linux {border-color: green; font-weight:bold;}

The Java Library ‘uasniffer’

When using Java, you can use the uasniffer library I wrote. It takes an agent string and transforms it to what can be used as CSS class names. For example, the following agent string:

Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)

is transformed to the following names:


Compiling the Library

To use this library, you need to get it from the Git version control system first:

git clone

This will create a uasniffer directory. Then go to that directory and compile it using Maven. E.g., from the command line:

mvn package

Implementation With a JSP

A JSP that would use this library could be written as follows:

<%@ page import="org.znerd.uasniffer.*" %><%
String agentString = request.getHeader("user-agent");
String uaClasses = AgentSniffer.analyze(agentString).getNamesAsString();
%><!doctype html>
<html lang="en" class="<%=uaClasses%>">
  <meta charset="utf-8">
  <link rel="stylesheet" href="style.css">
    <ul class="DownloadLinks">
      <li><a class="Windows" href="/install.exe">Windows installer (EXE)</a></li>
      <li><a class="Mac"     href="/install.dmg">Mac OS X installer (DMG)</a></li>
      <li><a class="Linux"   href="/install.tgz">Linux installer (TAR GZ)</a></li>


In general, avoid browser sniffing. When you do need it, the uasniffer library makes server-side browser sniffing extremely easy.

If this was helpful on your project, let me know.

Leave a comment

Posted by on 13 May 2011 in Geen categorie


>Opera also claims 100/100 on Acid3

>Although they don’t provide a publicly downloadable build yet (unlike WebKit), Opera also claims they have a score of 100/100 on Acid3. Coming soon to a download location near you…

Leave a comment

Posted by on 27 March 2008 in Geen categorie


>Browser blogs

>Here are links to some blogs dedicated to the main browser engines:

  • Microsoft Internet Explorer – since the release of the IE 8 beta, there are is one new post every day, mainly focusing on functionalities and technologies;
  • Mozilla Developer News – Covers not only browsers, but other products as well.
  • Camino – a blog dedicated to Mozilla Camino (for Mac OS X).
  • WebKit – the engine of -primarily- Safari.
  • Opera – Blog by Håkon Wium Lie, CTO of Opera.

For Konqueror, I could not find a decent blog…

Leave a comment

Posted by on 24 March 2008 in Geen categorie


>Tip: Getting a thread dump logged

>Quick tip: If you’re running a Java program and you want it to dump the status of the threads, this will work on the Apple, Sun and IBM JVMs (on UNIX/Linux):

kill -3 pid

Leave a comment

Posted by on 5 November 2007 in Geen categorie


>Remote VNC via SSH tunnel

>Quick tip: To use VNC through an SSH tunnel, make SSH bind to a local port while connecting it to a remote port. Then just connect your VNC master application to the local port.

Setting up an SSH tunnel goes as follows:

ssh -N -Llocalport:remoteip:remoteport intermediate_machine

For example, if you have a remote machine at behind a server you can connect to with SSH, do:

ssh -N -L5900:

Press Ctrl-C to kill the tunnel.


>Undo recent Subversion commits (updated)

>Here’s a quick HOWTO for undoing recent Subversion commits. Do:

svn merge -r NEW:OLD PATH


  • NEW is the new (bad) revision;
  • OLD is the old (good) revision;
  • PATH is the file or directory to revert.

For example:

svn merge -r 1680:1667 src/


  • Don’t forget to commit afterwards.
  • Instead of a revision number, you can also use the literal string HEAD for the most recent revision.
  • You can only pass one path at a time, but this can be a directory name instead of just a file name. To process multiple paths in a row on a UNIX/Linux/Mac system, use:
    for f in path1 path2 path3; do svn merge -r NEW:OLD $f; done

Updated (Nov. 27, 2008): Added some hints.


>Minor Mac Mail annoyances

>Overall, the Mail program on the Mac is simple and intuitive. But after searching intensively, I found one thing I think could be improved:

  • When replying to a message I wrote, I would expect the To: and CC: fields to remain the same. Instead, all the addresses in there are moved to the CC: field and the To: field is set to the original author (me).
Leave a comment

Posted by on 24 November 2006 in Geen categorie