Préambule

  • Pour un résumé des différentes alternatives pour développer une application mobile à base de JS, se référer à l'introduction de l'article TD n°4 : dev. mobile hybride - partie I, avec quasar
  • De plus, cet article donne également les étapes de mise en place de l'environnement de développement pour android. Elles ne seront donc pas rappelées ici.

 

1°/ Mise en place logicielle 

 

1.1°/ Installation d'android studio & ...

 

  • Comme pour quasar, ionic nécessite d'avoir à sa disposition android studio ou xcode afin de construire une application mobile, quand bien même celle-ci est hybride.
  • Pour l'installation des outils android, se référer à l'article précédent TD n°4 : dev. mobile hybride - partie I, avec quasar
  • A noter qu'avec ionic, l'installation séparée de gradle n'est à priori pas nécessaire car ionic-vue sait utiliser le plugin gradle pour android studio.

 

1.2°/ Installation des paquets node pour ionic

  • Il suffit d'utiliser npm pour faire un installation globale :
npm install -g @ionic/cli

 

1.3°/ Utilisation de la version 11/17 de Java

  • Comme pour quasar, il faut utiliser la v11/17 de Java

 

2°/ Création d'un projet ionic-vue

2.1°/ Initialisation du projet

  • Le plus simple est de partir d'un projet d'exemple créé avec les commande ionic :
ionic start monappli blank --type vue
  • le paramètre monappli correspond au nom de répertoire racine du projet. 
  • le paramètre blank correspond au type de projet généré, dans le cas présent quasi vide. Pour vue, il existe également tabs, sidemenu, list (cf. ionic start -l --type vue)

 

 
  • Une fois le projet créé on retrouve la structure similaire de celle produite par vue create ...
  • Cependant, les fichiers sont écrits en typescript et c'est la syntaxe v3 de vue qui est utilisée.

2.2°/ migration vers javascript (optionnel)

  • Pour ceux qui n'aiment pas le typescript, il est possible de "downgrader" le projet nouvellement créé vers du javascript.
  • Pour cela, il suffit de suivre les indications données ici : https://ionicframework.com/docs/vue/quickstart ou bien d'utiliser le shell script ionic2js.sh .
  • Pour utiliser ce script, il suffit de le copier dans le répertoire du projet créé et de le lancer.
  • Exemple :
ionic start myapp sidemenu --type vue
cd myapp
bash ionic2js.sh

 

2.3°/ Lancement du projet en mode Web

  • Comme avec quasar, il est tout à fait possible de développer une application web classique avec ionic et la tester dans un navigateur.
  • Pour cela :
ionic serve
  •  Comme avec quasar, ou vue/cli, le serveur se lance en mode "refresh on update". Il est donc possible de modifier les sources et de voir immédiatement le résultat des changements dans le navigateur.

 

2.4°/ Intégration de capacitor

  • Pour développer une application mobile ionic, il faut ajouter capacitor au projet et spécifier une architecture cible. Par exemple, pour android :
ionic cap add android
ionic cap sync
  • La deuxième ligne sert à faire un premier build de l'application afin de générer tous les scripts nécessaires à la compilation du projet.

 

  • Ensuite, il y a 2 façon de lancer l'application sur mobile.
  • La première consiste à lancer android studio, ce qui permet par exemple de modifier les fichiers manifests, notamment pour que l'application demande à l'utilisateur le droit d'accéder à certaines fonctionnalités/matériel du mobile. Pour cela, on tape :
ionic cap open android
  • Ensuite, on peut lancer l'exécution de l'application dans android studio, avec le simulateur de mobile de notre choix.
  • L'inconvénient de cette solution est qu'elle n'est pas "refresh on update". Si on modifie le code source JS, il n'y aura pas d'actualisation dans le simulateur du mobile.

 

  • La deuxième solution consiste à lancer un serveur de développement et de lancer un émulateur android, qui va lui-meme ouvrir son navigateur et demander l'URL du serveur de dev.
  • Cela nécessite de connaître les ID des simulateurs de mobile existants. On peut avoir leur liste avec :
inoic cap run android --list
  •  Ensuite, si on suppose qu'un des simulateurs s'appelle Pixel_2_API_30, on tape :
ionic cap run android -l --external --target Pixel_2_API_30
  • Pour cette solution, le "refresh on update" fonctionne parfaitement.
  • NB : par défaut, le serveur de développement est ainsi lancé sur http://localhost:8100, et aussi avec l'adresse IP vu de l'extérieur.
  • On peut même utiliser cette solution sur avec un vrai mobile branché sur l'ordinateur. Dans ce cas, son ID doit apparaître dans la liste.
ATTENTION ! Avec un vrai mobile, il faut être sur que son adresse IP soit dans le même réseau que celui de la machine de développement, ce qui est généralement le cas si le mobile et l'ordinateur obtiennent leur adresse IP via la même borne Wifi. Sinon, le mobile ne pourra pas accéder à l'URL du serveur de dev.

 

  • Autre option, on peut lancer le serveur de dev. ET android studio, ce qui permet ensuite de choisir le simulateur pour lancer l'exécution.
ionic cap run android -l --external --open

 

3°/ Exemples

3.1°/ Prendre une photo

  • On suppose que l'on part d'un projet nommé ionicphoto, créé avec le template blank, que l'on a downgradé en JS et où android a été ajouté.
  • Comme pour quasar, la première chose à faire est d'installer le plugin @capacitor/camera et @ionic/pwa-elements. En étant dans l'arborescence du projet, on tape :
npm install @ionic/pwa-elements
npm install @capacitor/camera
  • Pour que les pwa-elements soient disponibles dans l'application, il faut modifier le script principal src/main.js (ou main.ts si vous êtes toujours en typescript) comme suivant :
... // on garde tout depuis le début jusqu'à :
import './theme/variables.css'

// ajout des pwa-elements
import { defineCustomElements } from '@ionic/pwa-elements/loader';
defineCustomElements(window);

... // on garde la suite

 

  • Ensuite, éditer le fichier src/views/HomePage.vue et modifier le template et le script avec :
<template>
  <ion-content>
    <ion-header :translucent="true">
      <ion-toolbar>
        <ion-title>Blank</ion-title>
      </ion-toolbar>
    </ion-header>

    <img :src="imageSrc" />
    <ion-button @click="takePhoto()">Take Photo</ion-button>
  </ion-content>
</template>

<script setup>
import { IonContent, IonHeader, IonTitle, IonToolbar, IonButton } from '@ionic/vue';
import { ref } from 'vue';
import { Camera, CameraResultType } from '@capacitor/camera';

const imageSrc = ref('');
const takePhoto = async () => {
  const image = await Camera.getPhoto({
    quality: 90,
    allowEditing: true,
    resultType: CameraResultType.Uri,
  });

  imageSrc.value = image.webPath;
};
</script>

 

3.2°/ Une galerie de photo, avec sauvegarde locale

 

Remarques :

  • Les photos sont sauvegardées localement en tant que fichier à des emplacements différents selon la plateforme d'exécution.
  • Si c'est un navigateur desktop, les images sont placées dans le répertoire de votre profil utilisateur du navigateur, au sein d'un fichier texte représentant un BdD.
  • Si c'est un mobile, les images sont enregistrées sur le disque, ou disons plutôt la carte mémoire.
  • Même si capacitor permet d'abstraire relativement bien le matériel, il y a quand même des différences qui nécessitent d'écrire du code qui tient compte de la plateforme.
  • C'est notamment le cas avec la caméra qui produit un résultat différent et qu'il font donc parfois traiter afin de sauvegarder l'image avec le même format, quel que soit la plateforme.
  • Par exemple, pour une appli mobile, le plugin caméra renvoie directement un objet contenant le chemin d'accès à l'image en mémoire, que l'on peut donc lire directement, grâce aux fonctions de lecture fournies par capacitor (cf Filesystem.readFile() ) et obtenir une chaîne de caractère encodée au format base64, représentant l'mage. Cette chaîne peut ensuite être utilisée pour une sauvegarde dans un fichier local (cf. Filesystem.writeFile() )
  • En revanche, pour une appli desktop, ce plugin renvoie une URL, et il faut donc faire une requête HTTP (bien entendue purement locale) pour récupérer les données, par exemple grâce à la fonction fetch(). Le résultat doit encore être converti au format base64, avant de pouvoir être sauvegardé localement.