Bonjour à tous! Dans ce tutoriel nous allons voir comment créer une application Ionic pour scanner et créer des QR Code.

Ceux sont des fonctionnalités de plus en plus utilisée dans les réseaux sociaux (Snapchat, Messenger, YouTube) Mais également dans beaucoup d’autres application.

Par exemple des applications de Bitcoin comme BitPay utilisent ces fonctionnalités que nous allons prendre en main aujourd’hui.

Pour la lecture et la création de QR Code, nous utiliserons en fait deux plugins différents. Sachez que pour ces deux fonctionnalités, il existe d’autres plugins qui font le même travail.

J’ai simplement sélectionné pour vous les plus simples et les plus efficaces pour nos applications Ionic 4.

IONIC QR CODE: Comment lire et créer des QR Code avec Ionic ?

Pour ce tutoriel Ionic 4, nous allons suivre les étapes suivates:

  1. Créer un QR Code avec Ionic
  2. Transformer n’importe quel texte en QR Code dans Ionic
  3. Scanner un QR Code avec Ionic
  4. Récupérer le contenu du QR Code et l’afficher
  5. Ouvrir l’URL du QR Code depuis Ionic

Vous pouvez commencer ce tutoriel par créer votre application Ionic avec le framework Angular:

ionic start qrcode blank --type=angular

On commencera le tutoriel Ionic par la création d’un QR Code, car c’est la fonctionnalité la plus simple à mettre en pratique.

Comment créer un QR Code avec Ionic ?

Générer un QR Code avec Ionic, c’est en fait très simple. Si vous effectuez quelques recherches sur le site de NPM, vous trouverez de nombreux plugin JavaScript pour créer des QR Code.

La plupart d’entre eux utilise la bibliothèque primaire QRCode.js, pour générer les QR Code.

Le plugin que nous allons utiliser aujourd’hui ne fait que l’adapter à Angular et à nos applications Ionic.

Le plugin en question s’appelle angularx-qrcode, et je vous invite à jeter un œil à sa documentation: https://github.com/cordobo/angularx-qrcode

On commence comme d’habitude par installer ce plugin dans notre application Ionic avec un commande npm:

npm install angularx-qrcode --save

Attention: Pour que le plugin fonctionne et soit compatible avec votre version d’Ionic et d’Angular, vous devez modifiez rapidement le fichier suivant:

tsconfig.json

Vous devez modifier la propriété target, de es2015 à es5 comme ceci:

"target": "es5"

Cela vous évitera des bogues que j’ai rencontré lors des tests de l’application sur navigateur.

On passe maintenant à l’importation et à la déclaration du plugin, non pas de le fichier globale app.module.ts mais dans celui de votre page d’accueil directement:

src/app/home/home.module.ts

Importez tout d’abord votre plugin QRCodeModule:

import { QRCodeModule } from 'angularx-qrcode';

Puis déclarez-le dans votre tableau imports, pour pouvoir l’utiliser dans votre page d’accueil:

imports: [
  QRCodeModule,
]

L’importation et la déclaration du plugin sont maintenant terminées, on peut afficher très rapidement notre premier QR Code.

Pour cela rendez-vous dans votre fichier HTML:

src/app/home/home.page.html

Et copiez-y le code HTML suivant pour afficher un simple QR Code:

<qrcode [qrdata]="'Votre chaîne de caractère QR code'" [size]="256" [level]="'M'"></qrcode>

On utilise la nouvelle balise qrcode, avec tous les paramètres nécessaires notamment le texte à encoder: qrdata.

Vous pouvez faire un test et changer la valeur du texte à encoder, par exemple mettre l’URL d’un site web et de lire le QR Code avec votre smartphone.

<qrcode [qrdata]="'drissas.com'" [size]="256" [level]="'M'"></qrcode>

Voilà, nous venons de voir comment créer très rapidement un premier QR Code avec Ionic.

Voyons maintenant comment encoder n’importe texte depuis notre application.

Comment transformer n’importe quel texte en QR Code avec Ionic ?

Pour commencer nous allons créer une formulaire, avec un champ input et un bouton pour entrer du texte et le convertir en QR Code.

On positionne notre ion-input dans un ion-item, de manière classique pour proposer un affichage propre:

<ion-item lines="none">
  <ion-label><b>Texte à encoder:</b></ion-label>
  <ion-input [(ngModel)]="textToCode" placeholder="Entrez votre URL"></ion-input>
</ion-item>

Et on associe bien sûr notre champ texte input à une variable texte, ici la variable textToCode que nous allons déclarer:

public textToCode: string;

Une fois notre champ input créé, nous à la suite créer un bouton pour générer le nouveau QR Code:

<ion-button color="tertiary" expand="block" (click)="createQRCode()" *ngIf="!showCamera">
  <ion-icon slot="start" name="create"></ion-icon>
  Créer un QR Code
</ion-button>

Le bouton est associé à la fonction createQRCode() que nous allons déclarer juste après.

Une des subtilité du plugin QR Code que nous utilisons, est que tout le travail se fait dans le HTML. Notre balise <qrcode> contient l’attribut qrdata, auquel vous pouvez affecter n’importe quelle chaîne de caractère.

Nous créons donc une deuxième variable, pour créer la version définitive de notre QR Code:

public myAngularxQrCode: string = null;

Ainsi, dans la fonction createQRCode() nous transférons simplement la valeur de notre champ texte, et nous réinitialisations celui-ci pour vider le formulaire:

createQRCode() {
  this.myAngularxQrCode = this.textToCode;
  this.textToCode = "";
}

Une fois que la fonction est créé, on peut modifier la valeur de l’attribut qrdata de notre qrcode et lui affecter la variable myAngularxQrCode:

<div class="center" *ngIf="myAngularxQrCode">
  <qrcode [qrdata]="myAngularxQrCode" [size]="250" [level]="'M'"></qrcode>
</div>

Je contient également cette balise qrcode dans une boîte div, avec la condition de ne l’afficher que si la variable myAngularxQrCode n’est pas vide (car est QR Code est généré mais renvoie au caractère vide sinon).

Et je donne également à cette boîte la classe center, pour lui donner la même largeur que mon QR Code (ici 250px) et le centrer:

.center {
    margin-left: auto;
    margin-right: auto;
    width: 250px;
}

Voilà, nous sommes maintenant capables de générer un QR Code pour n’importe quel texte, URL ou informations.

N’hésitez-pas à faire des tests et à scanner ces qrcode avec votre smartphone.

Comment scanner un QR Code avec Ionic ?

Nous passons maintenant à la deuxième fonctionnalité, celle consistant à ouvrir la caméra de notre smartphone et à scanner un QR Code.

Cette fois-ci, Ionic nous propose un seul plugin pour réaliser cette fonctionnalité, et qui utilise Cordova pour accéder à l’appareil photo.

Je vous laisse donc le lien de la documentation Ionic du plugin QR Scanner: https://ionicframework.com/docs/native/qr-scanner

Ainsi que la documentation GitHub beaucoup plus complète du plugin QR scanner: https://github.com/bitpay/cordova-plugin-qrscanner

Pour installer ce plugin, vous devez entrer les lignes de commandes suivantes (une commande Cordova et une NPM):

ionic cordova plugin add cordova-plugin-qrscanner
npm install @ionic-native/qr-scanner

Puis nous allons importer et déclarer ce plugin, cette fois-ci dans le fichier globale:

src/app/app.module.ts

On commence par importer le plugin QRScanner en haut de notre page:

import { QRScanner } from '@ionic-native/qr-scanner/ngx';

Puis on le déclare dans le tableau providers à la suite du plugin SplashScreen:

providers: [
  StatusBar,
  SplashScreen,
  QRScanner,
  { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],

Nous pouvons maintenant accéder aux fonctionnalités de ce plugin dans notre page Home. Rendez-vous pour commencer dans votre fichier TypeScript:

src/app/home/home.page.ts

Puis importez cette fois-ci deux modules qui nous seront utiles pour ouvrir notre caméra et scanner les QR Codes:

import { QRScanner, QRScannerStatus } from '@ionic-native/qr-scanner/ngx';

Déclarer ensuite le module QRScanner dans votre constructor():

constructor(
  private iab: InAppBrowser,
  private qrScanner: QRScanner,
  public alertController: AlertController
) {}

Et maintenant que l’installation et l’importation de notre plugin est terminée, nous pouvons enfin faire notre premier test.

Pour cela je vous propose la fonction préconçue que vous pouvez retrouver dans la documentation officielle:

scancode() {
  this.qrScanner.prepare()
  .then((status: QRScannerStatus) => {
     if (status.authorized) {
       // camera permission was granted

       // start scanning
       let scanSub = this.qrScanner.scan().subscribe((text: string) => {
         console.log('Scanned something', text);

         this.qrScanner.hide(); // hide camera preview
         scanSub.unsubscribe(); // stop scanning
       });

     } else if (status.denied) {
       // camera permission was permanently denied
       // you must use QRScanner.openSettings() method to guide the user to the settings page
       // then they can grant the permission from there
     } else {
       // permission was denied, but not permanently. You can ask for permission again at a later time.
     }
  })
  .catch((e: any) => console.log('Error is', e));
}

Cette fonction permet de vérifier l’accès à la caméra de votre smartphone, puis de scanner les QR Codes qui apparaîtssent.

Si un QR Code est scanné, on affiche dans la console don contenu pour le moment.

Vous pouvez exécuter cette fonction au lancement de votre page en l’exécutant dans votre constructor():

constructor(
  private iab: InAppBrowser,
  private qrScanner: QRScanner,
  public alertController: AlertController
) {
	this.scancode();
}

Le dernier détail pour faire scanner un QR Code, est de rendre le fond de votre page transparent.

En fait la caméra lorsqu’elle sera ouverte s’affichera en fond de votre écran, on la voir il faut donner à notre ion-content un fond transparent:

ion-content {
    --ion-background-color: transparent;
}

Vous pouvez maintenant tester le fonctionnement de votre scan en créant une version Browser de votre application.

Cela vous permettra de tester toutes les fonctionnalités natives de vos smartphones sans quitter votre ordinateur et votre navigateur.

Entrez la commande suivante pour ouvrir (et d’abord générer) la version browser de votre application:

ionic cordova run browser

Cette partie ne consistait qu’un test rapide de cette fonctionnalité, nous allons maintenant faire en sorte de proposer une application plus propre.

Comment récupérer le contenu du QR Code et l’afficher ?

Nous avons bu comment rapidement tester le fonctionnement du scan de QR Code, mais l’interface de notre application n’est vraiment pas terrible.

Nous allons permettre d’afficher lors du scan uniquement la caméra ainsi qu’un cadre pour cibler le QR Code.

Une fois que le scan est terminé, nous allons afficher les informations récupérer par le QR Code.

On commencer donc par créer deux variables, une booléenne et une chaîne de caractère:

public showCamera = false;
public textScanned: string = '';
  • showCamera va nous permettre de cacher ou d’afficher le contenu HTML de notre page d’accueil en fonction de la présence de la caméra
  • textScanned va nous permettre de stocker le résultat du scan et de l’afficher dans notre page Home

On continue en créant le bouton pour ouvrir le scan, qui cette fois ne s’exécutera pas au lancement de ma page.

On associe évidemment ce bouton à notre fonction scanCode() définie précédemment:

<ion-button expand="block" (click)="scanCode()" >
  <ion-icon slot="start" name="qr-scanner"></ion-icon>
  Scanner un QR Code
</ion-button>

Puis nous créons un champ texte pour afficher le contenu de notre QR Code scanné. On le contient dans un ion-item et dans un ion-label:

<ion-item *ngIf="textScanned" lines="none">
  <ion-label>
    <p>Texte du QR Code</p>
    <h2><b>{{ textScanned }}</b></h2>
  </ion-label>
</ion-item>

On utilise la directive *ngIf pour vérifier que la variable textScanned n’est pas vide et donc qu’on a bien scanné un QR Code.

Donc tant que nous n’avons rien scanné, nous n’afficherons pas cette partie.

Pour finir je contient tout ce bloc HTML dans une boîte div à laquelle j’ajoute la condition *ngIf=”!showCamera” pour ce l’afficher que lorsque la caméra est fermer:

<div *ngIf="!showCamera">
  <ion-item *ngIf="textScanned" lines="none">
    <ion-label>
      <p>Texte du QR Code</p>
      <h2><b>{{ textScanned }}</b></h2>
    </ion-label>
  </ion-item>
  <ion-button expand="block" (click)="scanCode()" >
    <ion-icon slot="start" name="qr-scanner"></ion-icon>
    Scanner un QR Code
  </ion-button>
</div>

Je créé une autre boîte div avec la même directive *ngIf=”!showCamera” pour l’affichage de mon QR Code:

<div *ngIf="!showCamera">
  <ion-item lines="none">
    <ion-label><b>Texte à encoder:</b></ion-label>
    <ion-input [(ngModel)]="textToCode" placeholder="Entrez votre URL"></ion-input>
  </ion-item>

  <ion-button color="tertiary" expand="block" (click)="createQRCode()" *ngIf="!showCamera">
    <ion-icon slot="start" name="create"></ion-icon>
    Créer un QR Code
  </ion-button>
  <br>

  <div class="center" *ngIf="myAngularxQrCode">
    <qrcode [qrdata]="myAngularxQrCode" [size]="250" [level]="'M'"></qrcode>
  </div>
</div>

De cette manière lorsque nous ouvrirons la caméra, la page sera complètement vidé de son contenu.

On propose également un bouton fermer dans notre header pour fermer la caméra et arrêter le scan:

<ion-button *ngIf="showCamera" (click)="closeCamera()">
  <ion-icon name="close"></ion-icon>
</ion-button>

Nous n’affichons ce bouton que si la caméra est ouverte, grâce à la directive et condition *ngIf=”showCamera” et on l’associe à la fonction closeCamera() que nous allons déclarer juste après:

<ion-header>
  <ion-toolbar>
    <ion-title>
      Ionic QR Code
    </ion-title>
    <ion-buttons slot="end">
      <ion-button *ngIf="showCamera" (click)="closeCamera()">
        <ion-icon name="close"></ion-icon>
      </ion-button>
    </ion-buttons>
  </ion-toolbar>
</ion-header>

On peut maintenant s’attaquer à la partie TypeScript pour mettre à jour pour commencer la fonction scanCode().

On lui indique la valeur de la variable booléenne showCamera à true lorsqu’on lance la fonction. Puis lorsque le scan est terminé, on passe sa valeur à false:

scanCode() {
  this.showCamera = true;
  // Optionally request the permission early
  this.qrScanner.prepare()
  .then((status: QRScannerStatus) => {
    if (status.authorized) {
      // start scanning
      console.log('Scan en cours...' + JSON.stringify(status));
      const scanSub = this.qrScanner.scan().subscribe((text: any) => {
        console.log('Scanned something', text.result);
        this.textScanned = text.result;
        this.qrScanner.hide(); // hide camera preview
        scanSub.unsubscribe(); // stop scanning
        this.showCamera = false;
      });
    } else if (status.denied) {
      // camera permission was permanently denied
    } else {
      // permission was denied, but not permanently. You can ask for permission again at a later time.
    }
  })
  .catch((e: any) => console.log('Error is', e));
}

On stocke également le résultat du scan, et notamment sa valeur texte dans notre variable textScanned dont nous allons afficher le contenu dans le HTML.

On peut maintenant créer aussi la fonction pour fermer la caméra, mais aussi arrêter le scan en cours.

Pour cela on affecte à la variable showCamera la valeur false, mais on exécute aussi les fonctions du plugin qrScanner pour arrêter le scan et masquer la caméra:

closeCamera() {
  this.showCamera = false;
  this.qrScanner.hide(); // hide camera preview
  this.qrScanner.destroy();
}

Pour finir, comme dans la plupart des applications de scanner de code barre ou de QR Code, on propose un cadre par dessus notre caméra pour cibler notre code.

Pour cela on utilise l’icône Ionic du QR Code, que l’on affiche que si la caméra est ouverte, et à laquelle on donne la classe frame (pour cadre) que nous allons déclarer juste après:

<ion-icon *ngIf="showCamera" class="frame" name="qr-scanner"></ion-icon>

On donne maintenant quelques propriétés CSS à notre classe frame, pour positionner notre icône au centre de l’écran, et pour lui donner une couleur grise et une taille assez grande:

.frame {
    color: #d5d5d5;
    height: 350px;
    width: 350px;
    position: absolute;
    left: 0;
    right: 0;
    top: 0;
    bottom: 0;
    margin: auto;
}

Voilà, vous disposer maintenant d’une application lecteur de QR Code assez performante à l’ergonomie simplifiée.

Nous allons finir ce tutoriel Ionic avec la capacité à ouvrir le lien du QR Code que nous venons de scanner.

Comment ouvrir l’URL du QR Code dans le navigateur ?

Comme prévu on finit ce tutoriel Ionic par la capacité consistant à ouvrir le lien que vous avez récupéré de votre QR Code.

Cette fonctionnalité fonctionnera sur iOS, Android et Browser pour ouvrir le lien question dans votre navigateur natif: iOS (Safari), Android (Chrome).

Le plugin que nous allons utiliser est le suivant: Ionic In App Browser: https://ionicframework.com/docs/native/in-app-browser

À la base, comme son nom l’indique ce plugin permet d’ouvrir dans votre application un navigateur intégré, et donc d’ouvrir un lien sans quitter l’application.

Personnellement, je n’aimes pas trop cette fonctionnalité, je vais donc vous montrer comment ouvrir un lien dans votre navigateur natif.

On commence par installer le plugin comme d’habitude avec deux commandes à entrer:

ionic cordova plugin add cordova-plugin-inappbrowser
npm install @ionic-native/in-app-browser

Puis on initialise ce plugin dans le fichier globale:

src/app/app.module.ts

On commence par importer le plugin:

import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';

Puis on le déclare le plugin dans le tableau providers:

providers: [
  StatusBar,
  SplashScreen,
  QRScanner,
  InAppBrowser,
  { provide: RouteReuseStrategy, useClass: IonicRouteStrategy }
],

On peut maintenant passer à l’importation du plugin dans la page Home et le fichier:

src/app/home/home.page.ts

On importe le plugin en haut de notre page:

import { InAppBrowser } from '@ionic-native/in-app-browser/ngx';

Puis on le déclare dans le constructor():

constructor(
  private iab: InAppBrowser,
  private qrScanner: QRScanner,
  public alertController: AlertController
) {}

On peut enfin passer à son utilisation, à savoir la création d’une fonction pour ouvrir n’importe quel lien.

On lui indique plusieurs paramètre, notamment le lien que l’on souhaite ouvrir (link) mais également la destination ici ‘_system’:

openLink(link: any) {
	const browser = this.iab.create(link, '_system', 'location=yes');
}

En fonction du deuxième paramètre, on va ouvrir le lien dans le navigateur intégré, ou dans un navigateur externe. À vous de choisir!

Nous pouvons maintenant ajouter la fonction openLink() dans notre ion-item avec l’attribut (click):

<div *ngIf="!showCamera">
  <ion-item *ngIf="textScanned" lines="none" (click)="openLink(textScanned)">
    <ion-label>
      <p>Texte du QR Code</p>
      <h2><b>{{ textScanned }}</b></h2>
    </ion-label>
    <ion-icon slot="end" name="open"></ion-icon>
  </ion-item>
  <ion-button expand="block" (click)="scanCode()" >
    <ion-icon slot="start" name="qr-scanner"></ion-icon>
    Scanner un QR Code
  </ion-button>
</div>

De cette manière lorsqu’on clique sur l’item, on ouvre notre lien (à condition que le texte scanné soit un lien) dans une autre page.