• 20 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 28/11/2019

Profitez des native features : le stockage de fichiers et le storage

Connectez-vous ou inscrivez-vous gratuitement pour bénéficier de toutes les fonctionnalités de ce cours !

Le stockage de fichiers

Actuellement, les photos sont enregistrées dans un dossier temporaire.  Ce dossier peut être supprimé par l'OS quand le stockage du téléphone commence à être trop rempli, par exemple, donc ce n'est pas le dossier idéal pour l'enregistrement des fichiers de vos utilisateurs.  Pour rendre plus durables ces fichiers, vous allez implémenter le plugin  File .  Commencez par l'installer :

ionic cordova plugin add cordova-plugin-file
npm install--save @ionic-native/file

Importez  File  depuis @ionic-native/file dans votre  AppModule  et ajoutez-le à l'array  providers .

Ensuite, importez-le dans  NewViewPage  et injectez-le dans le constructor :

  constructor(private formBuilder: FormBuilder,
              private modalCtrl: ModalController,
              private camera: Camera,
              private toastCtrl: ToastController,
              private natureViewService: NatureViewService,
              private navCtrl: NavController,
              private file: File) {
  }

Vous allez ensuite modifier  onTakePhoto() , notamment le callback  .then() , pour déplacer le fichier temporaire vers un dossier permanent :

  onTakePhoto() {
    this.camera.getPicture({
      destinationType: this.camera.DestinationType.FILE_URI,
      encodingType: this.camera.EncodingType.JPEG,
      mediaType: this.camera.MediaType.PICTURE,
      correctOrientation: true
    }).then(
      (data) => {
        if (data) {
          const path = data.replace(/[^\/]*$/, '');
          const filename = data.replace(/^.*[\\\/]/, '');
          const targetDirectory = cordova.file.dataDirectory;
          this.file.moveFile(path, filename, targetDirectory, filename + new Date().getTime())
            .then(
              (data: Entry) => {
                this.imageUrl = normalizeURL(data.nativeUrl);
                this.camera.cleanup();
              }
            )
            .catch(
              (error) => {
                this.toastCtrl.create({
                  message: error,
                  duration: 3000,
                  position: 'bottom'
                }).present();
                this.camera.cleanup();
              }
            )
        }
      }
    ).catch(
      (error) => {
        this.toastCtrl.create({
          message: error,
          duration: 3000,
          position: 'bottom'
        }).present();
      }
    );
  }

La méthode  moveFile()  prend quatre arguments :

  • le chemin du fichier original ;

  • le nom du fichier original ;

  • le chemin cible ;

  • le nom du fichier cible.

Il faut donc séparer le chemin du nom de fichier dans les données retournées par l'appareil photo : c'est ce que font les deux RegEx.  Ensuite, le dossier cible est celui mis à disposition par  cordova.file.dataDirectory  (qui correspond à un dossier différent pour chaque OS, mais qui correspond au dossier de données lié à l'application).  Pour éviter les erreurs TypeScript, il faut ajouter la ligne suivante en haut du fichier, entre les  import  et le décorateur  @Component  :

declare var cordova: any;

@Component({
  selector: 'page-new-view',
  templateUrl: 'new-view.html',
})
...

La variable  cordova  sera mise à disposition par Cordova au run-time — cette ligne permet simplement de rassurer TypeScript.

La méthode  moveFile()  retourne ensuite une Promise avec un  Entry  (à importer depuis@ionic-native/file ) en cas de succès, ou rejette en cas d'échec.  Dans le callback .then() , vous êtes donc certain de recevoir des données.  Dans l'objet de forme  Entry , vous avez une propriété  nativeURL  qui, après normalisation, peut être enregistrée.  Ensuite, la méthode  this.camera.cleanup()  supprime tous les fichiers temporaires.

Comme d'habitude, dans le callback  .catch() , vous affichez un toast avec le message d'erreur retourné et supprimez les fichiers temporaires avec  this.camera.cleanup() .

Maintenant que les photos sont enregistrées de manière plus durable, il serait intéressant d'enregistrer toutes les données afin de compléter cette application.

Storage

Actuellement, à chaque rechargement complet de l'application, les données sont perdues, car elles sont uniquement enregistrées dans un service.  Une solution à cela serait d'intégrer un backend.  Une autre — celle que vous allez employer ici — serait de stocker les informations localement sur le device.  Pour cela, vous allez utiliser le plugin  cordova-sqlite-storage  : 

ionic cordova plugin add cordova-sqlite-storage

Importez-le dans votre  AppModule  et appelez sa méthode  forRoot()  dans l'array  imports  :

  imports: [
    BrowserModule,
    IonicModule.forRoot(MyApp),
    IonicStorageModule.forRoot(),
    AgmCoreModule.forRoot({apiKey: 'AIzaSyDtomsm7eXWYIgxXUVzzuURGRJYWxwTbb8'})
  ],

Dans une application plus complexe, il pourrait être intéressant de créer un service séparé pour tout ce qui est interaction avec la base de données, mais dans le cas présent, il est parfaitement acceptable d'intégrer ces interactions à  NatureViewService .  Dans un premier temps, il faut y injecter  Storage. Pour cela, il faut rendre le service  Injectable  :

import { NatureView } from '../models/NatureView.model';
import { Subject } from 'rxjs/Subject';
import { Injectable } from '@angular/core';
import { Storage } from '@ionic/storage';

@Injectable()
export class NatureViewService {

  private natureViewList: NatureView[] = [];
  natureviewList$ = new Subject<NatureView[]>();

  constructor(private storage: Storage) {}

  emitList() {
    this.natureviewList$.next(this.natureViewList);
  }

  addNatureView(view: NatureView) {
    this.natureViewList.push(view);
    this.emitList();
  }
}

Vous allez maintenant y créer deux méthodes,  saveList()  et  fetchList()  :

  saveList() {
    this.storage.set('views', this.natureViewList);
  }

  fetchList() {
    this.storage.get('views').then(
      (list) => {
        if (list && list.length) {
          this.natureViewList = list.slice();
        }
        this.emitList();
      }
    );
  }

La méthode  storage.set()  associe  natureviewList  à la clé  views  dans le storage.  La méthode  storage.get()  retourne une Promise contenant les données reçues depuis le storage.  Ici, vous vérifiez qu'il y a bien un retour contenant au moins un élément, vous l'attribuez à  natureViewList  et vous faites émettre le Subject avec les données reçues.  Ajoutez donc un appel à  saveList()  dans  addNatureView()  :

  addNatureView(view: NatureView) {
    this.natureViewList.push(view);
    this.saveList();
    this.emitList();
  }

Ainsi, les données du storage sont mises à jour à chaque nouvelle NatureView.  Enfin, pour que l'application récupère les données du storage correctement, modifiez la méthode  ngOnInit()  de votre  HomePage  :

  ngOnInit() {
    this.natureViewListSubscription = this.natureViewService.natureviewList$.subscribe(
      (natureViews: NatureView[]) => {
        this.natureViewList = natureViews;
      }
    );
    this.natureViewService.fetchList();
  }

Avec cette dernière étape, l'application est terminée ! :D

Tout ce que vous avez appris dans ce cours vous permettra d'ajouter d'autres fonctionnalités si vous le souhaitez : par exemple, la possibilité de modifier ou de supprimer des NatureView, et de synchroniser les données avec un backend Firebase.  L'objectif de cette partie était de vous présenter quelques exemples des fonctionnalités natives mises à disposition par Ionic et Cordova, et leur fonctionnement. N'hésitez pas à creuser et à trouver d'autres possibilités qui peuvent vous intéresser.

Exemple de certificat de réussite
Exemple de certificat de réussite