Ionic Deploy : Des mises à jour déployées sans Store

Ionic Deploy

Les applications hybrides exécutent du code "web", contrairement aux applications natives qui exécutent du code compilé. Cette différence présente plusieurs atouts, dont la possibilité de faire du Hot Code Push.

Le terme hot code push nous vient, semble-t-il, de la communauté du framework Meteor. Comprenez "remplacement (de code) à chaud". Cette technique consiste à mettre à jour une application pendant son exécution, sans passer par le "Store". Imaginez : proposer une nouvelle fonctionnalité ou un patch sans attendre la validation de Google Play ou de l'App Store. Ou, comment réduire à quelques secondes un processus long de (parfois) plusieurs jours.

L'idée est de mettre à jour (par écrasement) les fichiers composant l'application (le dossier www du package) : HTML, CSS, JavaScript, images, polices d'écriture... Il n'est évidemment pas question de remplacer le package (binaire) lui-même, mais bien les fichiers chargés par la WebView de Cordova. Toute mise à jour nécessitant un changement du fichier binaire (ajout, mise à jour ou suppression de plugin, etc) doit passer par le Store.


Ionic Deploy (Android, iOs)

C'est la solution "facile" : peu de développement nécessaire, serveurs/hébergement déjà inclus, le tout mis en œuvre rapidement. Le terme "facile", ici, n'a rien de péjoratif. Comme le souligne l'excellent Rework :

Good Enough is Fine.

À l'heure où cet article est écrit, Ionic Deploy est toujours un service gratuit en version alpha. Les mises à jour sont hébergées sur Amazon S3.

Mise à jour du 23/11/2016 : Ionic Deploy a beaucoup évolué depuis l'écriture de cet article. Se référer au guide de migration écrit par l'équipe d'Ionic : l'objet global Ionic.Deploy n'existe plus, pas plus que sa méthode update. Ionic Deploy est maintenant un service à part entière de la plateforme "Ionic Cloud", devenue payante.

Création d'un projet Ionic

Considérons que vous n'ayez pas de projet Ionic en développement (sinon, sautez les premières étapes) et créons-le !

$ ionic start hot-deploy && cd hot-deploy

ionic-cli demande alors si vous souhaitez créer un compte ionic.io pour profiter des services comme les notifications Push et Ionic View, répondez Oui (Ionic Deploy est l'un de ces services).

Create an ionic.io account to send Push Notifications and use the Ionic View app?  
(Y/n): Y

Si vous comptez réellement entamer un développement, profitez-en pour installer les paquets nécessaires (et les plateformes cibles de votre choix ?) :

$ npm install
$ ionic platform add android
$ ionic platform add ios

Connexion à ionic.io

Ajoutez ensuite ionic-platform-web-client (interface entre l'application et ionic.io) au projet:

$ ionic add ionic-platform-web-client

Puis renseignez vos identifiants ionic.io créés précédemment :

$ ionic io init

Une fois connecté avec vos identifiants, ionic-cli se charge d'enregistrer une nouvelle application à votre liste. Chaque application est dotée d'un identifiant (app_id) et d'une clé API (api_key) utilisés par chaque service de la plateforme ionic.io (push, analytics, deploy...).


Ajout d'Ionic Deploy

Ionic Deploy est mis en œuvre (du côté de l'application) avec le plugin ionic-plugin-deploy. Il est responsable du téléchargement et de l'application des nouvelles mises à jour.

$ ionic plugin add ionic-plugin-deploy

Ionic Deploy propose initialement 3 canaux de déploiement : Production, Staging, Dev. Il est possible d'en créer de nouveaux. Par souci de simplicité, seul "Dev" est utilisé dans l'exemple qui suit. Vous avez évidemment la possibilité, au sein de l'application (en utilisant la méthode setChannel de l'objet Deploy), de changer le canal utilisé pour le téléchargement des mises à jour.

Mise en œuvre

J'ai développé un service Angular simplifiant la vérification et l'application des mises à jour. La création d'un service intermédiaire présente aussi l'avantage de découpler un peu plus le code de notre application du plugin Ionic Deploy.

Voici le code simplifié et "décommenté" utilisant le channel "dev" :

function UpdateDeployService() {  
    var self = {};
    self.deploy = new Ionic.Deploy();
    self.deploy.setChannel('dev');

    self.checkForUpdate = function(onSuccess, onError) {
        self.deploy.check().then(onSuccess, onError);
    };

    self.startUpdate = function(onSuccess, onError, onProgress) {
        self.deploy.update().then(function(result) {
            onSuccess(result);
        }, onError, onProgress);
    };

    return self;
}

Le callback onSuccess passé à checkForUpdate est exécuté avec un booléen : true si une mise à jour est disponible, sinon false. Il est important de noter que l'espace de nom Ionic (qui contient la function Deploy()) n'existe pas tant que le plugin n'est pas chargé : il faut par conséquent attendre que l'appareil soit "ready" pour utiliser ce code (cf. ionic.Platform.ready()).

Et l'utilisation (résumée) du service :

UpdateDeployService.checkForUpdate(function(updateAvailable) {  
    if (!updateAvailable) {
        return;
    }

    UpdateDeployService.startUpdate(function onSuccess() {
        console.log('Update: success');
    }, function onError() {
        console.log('Update: failure');
    }, function onProgress(percentage) {
        console.log(percentage);
    });
}, function onError() {
    console.log('Update: unable to check for new updates');
});

Par défaut, ce code télécharge et installe la dernière mise à jour disponible (s'il en existe une nouvelle). Une fois la mise à jour déployée, la Web View charge l'application à nouveau. Pour interagir avec l'utilisateur, nous pourrions :

  • Informer l'utilisateur de la disponibilité d'une mise à jour, à l'aide (par exemple) d'une popup Ionic ($ionicPopup)
  • et/ou Proposer le téléchargement de la nouvelle mise à jour (voir $ionicPopup#confirm()).
  • Afficher la progression du téléchargement
  • Laisser à l'utilisateur le choix de redémarrer l'application après l'installation (requiert de contrôler chaque étape du processus en utilisant le Mode Manuel)

Déploiement d'une mise à jour

Pour déployer une nouvelle mise à jour, il suffit simplement d'utiliser la commande "upload" de la CLI ionic :

$ ionic upload --note "Note de mise à jour" --deploy=dev

La mise à jour devient automatiquement la dernière Active :

Ionic Deploy Updates List

Il est possible de revenir à une mise à jour antérieure en utilisant le bouton "DEPLOY" de celle-ci, en bout de ligne.

Le plugin ionic-plugin-deploy s'occupe de la sauvegarde de l'uuid du dernier déploiement, ainsi que de la vérification de mises à jour. Il n'est donc pas nécessaire d'écrire d'avantage de code.


Cet article est divisé en deux parties : chaque partie présente une solution de Hot Code Push. L'alternative qui sera présentée dans un prochain article est le plugin Cordova Hot Code Push (HCP). Plus complexe à mettre en œuvre, il permet cependant de sélectionner les fichiers qui seront mis à jour et de n'uploader que ces derniers.