What are you building with Ionic? We want to know!

Thanks @iqlas!

For the webapp, we pretty much just have the webserver serve the www folder. We created a separate cordova hook to add <script src="cordova.js"></script> so that it won’t attempt to load in the webapp.

Anytime we use a cordova plugin, we have graceful degradation. E.g. for toast messages, if window.cordova exists, call $cordovaToast.showShortBottom; otherwise, use jqlite to create an absolute position div and $timeout to destroy it after a few seconds.

For the appcache, we did the following:

Update config.xml with the following

<content src="native-loader.html"/>
<platform name="android">
  <preference name="ErrorUrl" value="file:///android_asset/www/cordova-error-page.html"/>
</platform>
<platform name="ios">
  <preference name="ErrorUrl" value="cordova-error-page.html"/>
</platform>

The native-loader.html is a short HTML file that just uses javascript to redirect to index.html hosted on our server. We use a cordova hook to set the URL in native-loader.html by platform. Our webserver serves the latest copy of platforms/android/assets/www for android, and platforms/ios/www for ios.

The cordova-error-page.html is a friendly error page with a reload button, which is displayed if the user does not have internet when they first open the app (irrelevant once they have first downloaded the appcache).

Our index.html starts with <html manifest="cache.manifest">. We have a scala script that regenerates www/cache.manifest each time we deploy an upgrade, which includes a recursive list of files that need to be downloaded by the browser (including cordova/plugins).

The services.js file defines a constant with the latest version number. When it connects via websocket to the server, the browser sends the version number, and the server sends a response telling it whether or not it has to upgrade. If it has to upgrade, we display an $ionicPopup to ask the user to upgrade. When they tap the upgrade button, we run the following code:

$ionicLoading.show({template: 'Downloading update'});
var applyUpdate = function() {
  $ionicLoading.show({template: 'Installing update'});
  window.location.reload();
};
var appCache = window.applicationCache;
if (appCache.status === appCache.UNCACHED || appCache.status === appCache.OBSOLETE) {
  applyUpdate();
} else {
  appCache.addEventListener('error', function() {
    $ionicLoading.hide();
    var popupOpts = {
      title: 'Could not download update',
      template: 'There was a problem downloading the latest version of OpenLine. Please check that internet service is working on your device.',
      okText: 'Try again'
    }
    if (!mustUpgrade) popupOpts.cancelText = 'Later';
    var popupFn = mustUpgrade ? $ionicPopup.alert : $ionicPopup.confirm;
    popupFn(popupOpts).then(doUpgrade);
  });
  appCache.addEventListener('updateready', applyUpdate);
  appCache.addEventListener('noupdate', applyUpdate);
  appCache.update();
}

When a new user installs the app, the latest version will be downloaded automatically. When they reopen the app after a new version has been released, they’ll be prompted to update. When they have the app open during the upgrade process, the server will close all existing websockets, and when the browser reconnects they will resend their old version number and be prompted to upgrade.

3 Likes