Uw betrouwbare partner voor (mobiele) web applicaties
TwitterEmailRSS

Dynamically load phonegap.js per mobile platform

Recently I was wondering how to dynamically load phonegap.js per mobile platform. I mean, when using PhoneGap Build, you could just add

<script src="phonegap.js"></script>

to the <head/> of your page, but what about running your app outside PhoneGap Build in a Simulator, on your device, or even as a website locally on your laptop?

Dynamically load phonegap.js per mobile platform

Ofcourse there are more ways to solve the problem, but what we did was really easy and working extremely well: we load our own phonegap/cordova.js file based on the useragent while loading the page and don’t include it in the head at all. Your app supports all deployment scenario’s, even on PhoneGap Build.

The code: an easy bit of JavaScript

Add this to any .js file every page of your webapp needs Cordova functionality for. We’ve included it in a core.js file, which is included in the head of every page. Note that this app doesn’t use jQuery, but Vanilla.js, the fastest JS framework on the planet.

(function loadCordova() {
  var CORDOVA_VERSION = "2.1.0";

  var CORDOVA_EDITION = null;
  if (isAndroid()) {
    CORDOVA_EDITION = "android"
  } else if (isIOS()) {
    CORDOVA_EDITION = "ios"
  }

  if (CORDOVA_EDITION != null) {
    document.write('<script type="text/javascript" src="' + 'js/lib/cordova-' + CORDOVA_VERSION + '-' + CORDOVA_EDITION + '.js"></script>');
    // now add plugins
    if (isIOS()) {
      document.write('<script type="text/javascript" src="js/lib/keychain.plugin-ios.js"></script>');
      document.write('<script type="text/javascript" src="js/lib/certificatepinner.plugin-ios.js"></script>');
    }
  }
})();

Let me explain the highlighted lines:

Lines 5 & 7: Determine the platform by querying the useragent, nothing fancy, so didn’t include details.

Line 12: The correct version for your platform is loaded. By using document.write the library gets evaluated immediately and that’s what we want!

Line 19: Don’t wait for ‘document ready’ or similar events, we want the js evaluated right away.

Cordova LocalStorage cleared after first App launch on iOS 6

“OMG WTF ! ? “

That’s what we thought today when we were hunting a bug in a PhoneGap / Cordova iOS app.

Symptoms

Upon first launch of the app (in the simulator, from PhoneGap build, or the AppStore) the app saves registration info in LocalStorage. Next time the app launches, it checks LS and recognizes you as a known user.

However, upon the second launch, we had to register again and found out that the LS was empty!

The Problem: Cordova LocalStorage cleared

Googling around, we found it’s actually a known issue on iOS 6 in Cordova 2.1.0: Upon first launch, Cordova tells iOS to remember anything the app stores in LS. This is done with a flag. However, the flag is set too late, so anything put in LS on the first run is not saved to the correct location.

The next time the app is started (and any consecutive time for that matter), the flag has already been set and the LS will behave as you’d expect (surviving app restarts, crashes, app upgrades, etc).

The solution

With this blog we hope to save some fellow coders a few hours of bug hunting. The suggestion done by Christian Hemker in the issue mentioned previously is the right thing to do. We had to roll out a quick fix, so there was no time to upgrade to a newer version of Cordova; we had to patch Cordova 2.1.0 (this bugfix was released with Cordova 2.2.0).

Don’t forget to do a Product > Clean in XCode, so the Cordova files get recompiled along with your project upon the next build.

Using PhoneGap Build?

Unfortunately, it’s not currently possible to add your custom Java code to apps built with PhoneGap Build. But if you do use that great Adobe cloudservice, check out this nice new app we created: Buildmeister, a mobile app for managing your PhoneGap Build apps.

Download Buildmeister for these platforms:

Android app on Google Play

Buildmeister - X-Services