SlideShare une entreprise Scribd logo
Développement 

Mobile Web 

avec IONIC2
Version du 29/03/2017
Jean David Olekhnovitch
📧 jd@olek.fr
@gidehault
Web et mobile :
deux mondes à part
• Le web est basé depuis la fin des années 90 sur un mode orienté
serveur :

• Un serveur HTTP qui centralise tous les traitements

• Des clients HTML/CSS qui affichent passivement l’information

• De multiples tentatives existent pour ‘dynamiser’ le côté
client, Javascript en tête

• Un handicap : ça rappelle furieusement le modèle mainframe/
client texte des années 60/70

• Un souhait : préserver un standard ouvert
2
Web et mobile :
deux mondes à part
• Le mobile s’appuie sur des outils de
développements plus sophistiqués, mais dédiés à
des plateformes incompatibles entre elles
3
Android
- Langage Java
- Environnement propriétaire
Google, sur base Linux
- Développement Android
Studio
- Distribution : Google Play
iOS
- Langage Swift
- Environnement propriétaire
Apple, sur base NetBSD
- Développement XCode
- Distribution : App Store
FirefoxOS
Windows
Phone
Blackberry
Ubuntu
Tizen
…
Mais la mixité subsiste
• D’un côté, il est possible de faire tourner des
choses assez évoluées dans le navigateur de son
téléphone

• De l’autre, il est aujourd’hui possible d’accéder à
des fonctions ‘natives’ depuis son navigateur
5
1 - Historiquement : les
"sites mobiles"
• A l'époque des premiers smartphones, il était
nécessaire de faire une version spécifique des sites
Internet pour visualisation sur téléphone mobile
6
Avantages
‣ version légère et bien adaptée aux
smartphones peu performants
‣ facilité de développement
Inconvénients
‣ nécessité de gérer deux versions
en parallèle
‣ aucune exploitation des possibilités
natives des téléphones
2 - Vers une version unique des
sites web : le responsive design
• Les possibilités d'élasticité (grille fluide) et d'adaptation aux
devices (media queries) des feuilles de style CSS permettent
de maintenir une version unique des sites web tout en
s'adaptant au format d'affichage
7
Avantages
‣ adaptation relativement simple (que
des hacks CSS)
‣ une seule version des sites web à
maintenir
Inconvénients
‣ aucune exploitation des possibilités
natives des téléphones
3 - Un pas vers les fonctions
natives : HTML5
• La version HTML5 propose, de manière plus ou
moins aboutie, la possibilité d'accéder à certaines
fonctions natives depuis son navigateur web
8
Avantages
‣ possibilité de cumuler avec les
capacités de responsive design
‣ fonctions accessibles en quelques
balises
Inconvénients
‣ toutes les fonctions ne sont pas
présentes
‣ compatibilité aléatoire suivant les
navigateurs
Du HTML à l'app mobile : un
chemin semé d'embuches
9
Site
HTML/
CSS
Déclinaison
site mobile
Site
Responsive
Site HTML5
App mobile
native
App hybride
web/mobile
?
AppsSites
Progressive
Webapps
L’enjeu des fonctions natives
• Stockage offline

• Géolocalisation

• Gestuelles tactiles

• Bluetooth

• Accéléromètre, boussole…

• Notifications

• Caméra…
10
La barrière des appstore
• Google et Apple ont fait le choix du point d'entrée
unique vers l'application : l'app store (ou playstore)

• Pour diverses raisons de contrôle qualité, de
sécurité… et parfois de censure

• Cette barrière impose des critères techniques
nombreux et peu simples à franchir
11
1ères solutions : Apache
Cordova/Adobe PhoneGap
• Idée : proposer des passerelles entre les fonctions
natives, et des pages conçues en HTML/CSS

• Naissance du concept d’Application Hybride
• Aujourd’hui intégralement en opensource et géré
par l’Apache Foundation
12
Limitations de Cordova
• Ne propose pas de solution pour l’interface
utilisateur (gestuelles tactiles, etc…)

• La publication vers les stores Google/Apple reste
complexe

• A voir plus comme une série de librairies que
comme un framework a part entière
13
Surcouche et structuration:
la solution d'un framework
• Idée : compléter la philosophie (et les briques
techniques) de Cordova par un véritable framework
capable de :

• faciliter le développement

• industrialiser la publication sur les stores

• donner la possibilité de créer des modules
optionnels

• ‘casser’ la logique de page au sens HTTP du terme
14
Côté Facebook : React
• Framework développé en interne

• Destiné au développement des applications
Facebook avant tout

• Essentiellement côté « front » 

• Basé sur Javascript

• Fait appel à des composants natifs autant que
possible
15
Autres frameworks
• Onsen UI

• Intel XDK

• Sencha Touch

• Kendo UI

• Framework 7
16
• JQuery Mobile

• Mobile Angular UI

• Famo.us

• Monaca

• Trigger.IO

• Electron (pour applis desktop)
Ionic
• Créé en 2013

• Repose entièrement sur Cordova pour la partie native

• Et sur AngularJS pour la cinématique des pages

• v2 sortie fin 2016

• TypeScript remplace Javascript

• Angular2 remplace AngularJS
17
Angular 2
Architecture d’Ionic2
Apache Cordova
Angular 2
Ionic 2
HTML SCSS Typescript
NPM
NodeJS
Moteur HTML/CSS/JS
Natif
App
native Application
passerelle
vers le monde natif
cinématique des
écrans
framework
gestionnaire de paquets
environnement de
développement
affichage in-app
via un interpréteur web
Installation d’Ionic (1)
• Première étape : installation de NodeJS 6

• Inclut NPM (gestionnaire de paquet Javascript)

• https://nodejs.org/en/download/
19
Installation d’Ionic (2)
• Installation d’Ionic et de Cordova

• On se repose sur le gestionnaire de paquets
NPM

• Tout se passe en ligne de commande… comme
ça va être le cas pour toute la suite :

• npm install -g ionic cordova
20
Première app Ionic
• Génération du squelette :

• ionic start premierEssai super --v2
• On va dans le répertoire

• cd premierEssai

• Test dans un navigateur

• ionic serve -c --lab
21
Nom du
template qui sert de
modèle (blank, tabs,
sidemenu, tutorial …)
ionic peut à la fois créer
des apps ionic1 et ionic2
lancement avec
console de debug et choix de
l’émulateur
Visualisation sur un
téléphone
• Problème : on ne peut pas directement télécharger
une app sur un mobile (il faut passer par la
validation du constructeur)

• Contournement : l'app Ionic View qui permet de
visualiser un prototype de son app publié au
préalable sur les serveurs Ionic
22
Fonctionnement
d'Ionic View
23
Poste de travail
Serveur Ionic
Smartphone
App Ionic View
ionic upload
X
synchro
in-app
interdit
Nécessite la création d'un
compte sur http://ionic.io
Dispo sur AppStore
et GooglePlay
Installation d’Ionic (3)
• Modules supplémentaires

• Pour chaque module supplémentaire, là aussi on
utilisera npm :

• npm install ionic-native --save
• Les mises à jour se font elles aussi en ligne de
commande :

• npm update -g ionic
24
Gestion des
dépendances
Installation globale
Installation d’Ionic (4)
• Environnement iOS

• Il est obligatoire d’être sur Mac !

• Installation de XCode via le Mac App Store

• Déclaration dans ionic :

• sudo xcode-select -s /Applications/Xcode.app/
Contents/Developer
• sudo npm install -g ios-deploy --unsafe-perm=true --
allow-root
25
Installation d’Ionic (5)
• Environnement Android

• Passe par l’installation de Java (JDK, pas le JRE) : 

• http://www.oracle.com/technetwork/java/javase/downloads/index.html
• Installation d’Android Studio :

• https://developer.android.com/studio/index.html
• Installation des packages via le Open Android SDK Manager (‘android’ en ligne de
commandes)

• Android Platform SDK for vXXX

• Android SDK build-tools

• Android Support Repository

• Créer un Android Virtual Device (AVD) pour définir un émulateur type qui servira par la suite
26
Génération de l'icône et du
splash screen
• Les fichiers suivants doivent être stockés dans le
répertoire /resources de l'application

• icon.png : taille de 192x192

• splash.png : taille de 2208x2208

• La génération de toutes les déclinaisons de ces
images se fait ensuite par l'instruction suivante, à
lancer avant le build :

ionic resources
27
Lancement de son application
dans un environnement natif
• ionic platform add android
• ionic platform add ios
• ionic build ios
• ionic build android
28
Préparer un build iOS
• Double-cliquer sur 

• /platforms/ios/MonApp.xcodeproj
• Créer sur XCode un « Archive » 

• Publier ensuite sur le compte (payant !) Developer Apple
créé via

• https://developer.apple.com

• Gestion de la publication sur

• https://itunesconnect.apple.com
29
Préparer un build Android
• Création d’une clé :

• keytool -genkey -v -keystore MonApp.keystore -alias
MonApp -keyalg RSA -keysize 2048 -validity 10000
• Création du build (fichier .apk) prêt à être importé :

• ionic build android --release
• Création d’un compte puis publication sur 

• https://play.google.com/apps/publish/
30
Structuration d’une
app ionic
• /src : code source de l’application

• /resources : stockage de l’icône et du
splashscreen

• /platforms : version compilée par plateforme

• config.xml : fichier principal de configuration de
l’app
31
Structuration du 

répertoire /src
• /app : fichiers principaux de l’application

• /pages : les pages de l’application

• /assets : divers fichiers statiques (css, js, images…)

• /providers : les ‘providers’ (‘moteurs’) de l’application

• /theme : définition d’un thème pour l’application

• index.html : fichier de démarrage de l'app
32
Création d’une nouvelle
page
• Création des fichiers :

• ionic g page MonEssai
• J’obtiens un dossier /src/pages/mon-essai, 

• et 3 fichiers :

• mon-essai.html : interface de la page

• mon-essai.scss : style de la page

• mon-essai.ts : fonctions de traitement en amont et en aval
de la page (avec une classe qui s'appelle MonEssaiPage)
33
MonEssai
MonEssaiPage
nom de la classe
mon-essai
nom des fichiers
Déclaration d’une
nouvelle page
• Cette déclaration se fait dans le fichier global 

/src/app/app.module.ts :
import { MonEssaiPage } from '../pages/mon-essai/mon-essai';
• Le nom « MonEssaiPage » doit également être
mentionné dans les paragraphes :

• ‘declarations’

• ‘entryComponents’
34
Structure d'un fichier .ts
• Chaque fichier .ts d'une page (ici : mon-essai.ts) est
avant tout une classe

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'monEssai',
templateUrl: 'mon-essai.html'
})
export class MonEssaiPage {
// attributs
// méthodes
constructor(public navCtrl: NavController) {
}
} 35
Import
de librairies et fichiers
externes utiles
Les attributs sont
les variables utilisées
dans la classe
Les
méthodes sont des
fonctions utilisées dans
la classe
Le constructeur est la
méthode appelée au
démarrage de la page
Divers
paramétrages
Fin de la
classe
Liens entre .ts et .html
• Le fichier mon-essai.ts contient une classe (et
donc des attributs et méthodes) représentant la
partie dynamique de la page

• Le fichier mon-essai.html contient la description
des éléments visuels de la page

• Les deux communiquent intimement par le biais
des mécanismes d’Angular
36
TS, HTML, et MVC
On est en fait ici très proche du pattern MVC bien connu des
développeurs d'interface utilisateur

• Mais le contrôleur est ici géré de manière transparente par le
framework Angular
37
Vue
mon-essai.html
Contrôleur
Ionic/Angular
Modèle
mon-essai.ts
Affichage d’une variable
dans la page
• Prenons l’exemple d’un attribut de la classe 

(dans mon-essai.ts) :

export class MonEssaiPage {

unAttribut: string="un contenu";
• On affiche ensuite l'attribut au milieu du code de la page
mon-essai.html de la manière suivante :

<p>{{unAttribut}}</p>
• Nul besoin de préciser le nom de la classe ou de l’instance

• On verra plus tard que cette liaison est dynamique, et permet
la mise à jour du contenu de cette variable
38
Aller d’une page à l’autre (1)
• Pour aller à la nouvelle page, on commence par créer un
bouton dans le fichier .html de la page principale :

<button ion-button>Cliquez ici</button>
• On rajoute ensuite une mention '(click)' qui permet
d'indiquer le comportement à avoir lors d'un clic sur le
bouton 

<button ion-button (click)="boutonClic()">Cliquez ici</button>
39
Fonction qui sera
appelée lors du 'clic'
Aller d’une page à l’autre (2)
• On crée la fonction correspondante dans le fichier .ts de la page
principale:

boutonClic() {

this.navCtrl.push(MonEssaiPage);

}
• Pour fonctionner, ce code a besoin au préalable de deux éléments :

• La page MonEssaiPage doit être importée pour être connue

import {MonEssaiPage} from '../mon-essai/mon-essai';
• Le contrôleur de navigation ‘navCtrl’ doit être connu et déclaré :

import { NavController} from 'ionic-angular';
constructor(public navCtrl: NavController) {
40
Schéma récapitulatif
Cliquez ici
home.html
class HomePage
{
boutonClic()
{
this.navCtrl.push
(MonEssaiPage);
}
home.ts
{{unAttribut}}
mon-essai.html mon-essai.ts
class MonEssaiPage
{
unAttribut : string;
}
Démarrage
de l'app
Le constructeur d'une
classe de page
• Ce constructeur a des paramètres d'entrée qui fonctionnent de manière
"magique" : il suffit de les mentionner pour qu'ils :

• soient renseignés avec des objets déjà initialisés

• remplissent un attribut du même nom (rendant l'objet accessible dans toute
la classe)

• Cette 'magie' est en fait le pattern injection, géré par le framework

• Ces providers sont :

• Soit des contrôleurs standards d'ionic-angular (ex : NavController)

• soit déclarés dans app.module.ts (providers globaux à l'app)

• soit dans le bloc @Component de la page
42
Afficher des traces dans la
console
• Lancer ionic serve avec le paramètre -c permet
d'avoir une trace de la console dans le terminal, ce
qui est bien pratique pour débugger

• Vous pouvez n'importe où dans le code afficher
des éléments dans la console :

console.log("valeur de x :"+x);
• Vous pouvez également afficher des structures
complexes avec JSON.stringify :

console.log("erreur :"+JSON.stringify(err));
43
Composants ionic
• ionic2 est fourni avec de très très très nombreux
composants, pour gérer à peu près toute l’interface de
son app mobile

• Nous allons voir sur la suite de ce cours quelques uns de
ces composants, mais une bonne idée est de
commencer par les découvrir en regardant la page :

• http://ionicframework.com/docs/v2/components/
44
Rafraichissement d'une
page
• Pour proposer un rafraichissement d'une page, on
passe par le composant <ion-refresher>, à
positionner en tête de son <ion-content> :

<ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content
pullingIcon="arrow-dropdown"
pullingText="Tirer pour mettre à jour"
refreshingSpinner="circles"
refreshingText="Mise à jour...">
</ion-refresher-content>
</ion-refresher>
45
Récupérer la saisie d'un
champ de saisie
• On commence par créer dans la classe (côté .ts,
donc), un attribut nom qui récupérera le contenu

nom : string = "";
• Ensuite, dans la page (côté .html), on utilise le
component ion-input avec la propriété ngModel
qui va permettre de faire le lien avec l'attribut

<ion-input [(ngModel)]="nom"></input>
46
Créer une barre de
navigation (1)
• On peut passer par le template ‘tabs’ lors de la création de son
projet

• Mais il est également possible de construire manuellement sa
barre de navigation : 

• On commence par créer une ‘page’ qui ne contiendra que les
données de la barre de navigation :

• ionic g page Tabs
• On crée ensuite deux pages qui compléteront Home en tant
que pages pointées par la barre de navigation (pour
l'exemple : Actus, Pratique)
47
Créer une barre de
navigation (2)
• Cette page Tabs contient côté HTML la liste des entrées de la
barre :

<ion-tabs>
<ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
<ion-tab [root]="tab2Root" tabTitle="Actus" tabIcon="actus"></ion-tab>
<ion-tab [root]="tab3Root" tabTitle="Pratique" tabIcon="pratique"></ion-tab>
</ion-tabs>
• Le fichier .ts va permettre de lier à chaque entrée une page :

import { HomePage } from '../home/home';
import { ActusPage } from '../actus/actus';
import { PratiquePage } from '../pratique/pratique';
export class TabsPage {
tab1Root: any = HomePage;
tab2Root: any = ActusPage;
tab3Root: any = PratiquePage; 48
Créer une barre de
navigation (3)
• Dernière étape, cette page Tabs doit être déclarée
comme étant la page d’entrée de l’application, en
remplacement de Home 

• Cette opération se fait dans le fichier
app.components.ts :

import { TabsPage } from '../pages/tabs/tabs';
export class MyApp {
rootPage = TabsPage;
// rootPage = HomePage; // ancienne page d'entrée
49
Créer un menu latéral
• On peut passer par le template ‘sidemenu’ lors de
la création de son projet

• Mais il est également possible de construire
manuellement son menu
50
API REST et JSON
• Une API REST est un moyen de faire communiquer
un serveur et un client d’une manière souple,
simple et légère, en se basant :

• Sur le protocole de transfert HTTP (compatible
sur tous réseaux, léger, sécurisable) via ses
diverses déclinaisons : GET, POST, PUT, DELETE

• Sur l’encodage JSON des trames, pour pouvoir
transférer tout type de structure de données
51
JSON
• Ce format est une alternative plus légère à XML pour structurer des
données

• donnée simple : "name" : "Jean Dupont" 

• données multiples : "movies": ["titre1", "titre2"]
• structure complexe :

{
"name":"paul rudd",
"movies":[
"I Love You Man",
"Role Models"
],
}
52
Exemple d’API REST
• Nous allons partir sur l’exemple complet en ligne

https://reqres.in

• Cet exemple permet à la fois de trouver des exemples de
fonctionnement pour comprendre ce qu’est une API REST

• mais aussi de source pour pouvoir construire ses
premiers projets sans se soucier de la partie serveur

• NB : le CMS WordPress est depuis sa version 4.7 un
bon support pour diffuser facilement des données via
une API REST
53
Exemple de requête REST
simple
https://reqres.in/api/users/2 

avec la méthode GET permet de récupérer les données
du user 2

Données retournées :

{
"data": {
"id": 2,
"first_name": "lucille",
"last_name": "bluth",
"avatar": "https://s3.amazonaws.com/jstein/128.jpg"
}
}
54
L’id est directement
présent dans l’URL
Exemple de requête REST
de liste
• https://reqres.in/api/users/ (sans préciser d’id user) permet de
récupérer une liste

"page": "1",
"per_page": 3,
"total": 12,
"total_pages": 4,
"data": [
{
"id": 4,
"first_name": "eve",
"last_name": "holt",
"avatar": "https://s3.amazonaws.com/marcoramires/128.jpg"
},
{
"id": 5,
"first_name": "gob",
"last_name": "bluth",
"avatar": "https://s3.amazonaws.com/stephenmoon/128.jpg"
},
{
"id": 6,
"first_name": "tracey",
"last_name": "bluth",
"avatar": "https://s3.amazonaws.com/bigmancho/128.jpg"
}
]
} 55
Méthodes HTTP
• Même si ces méthodes sont indépendantes des
traitements, on les utilise communément pour les
usages suivants dans le cadre d’une API REST :

• GET : lecture de données

• POST : création de données

• PUT : mise à jour de données

• DELETE : suppression de données
56
Les codes d'erreur sont également 

mis à contribution :

• 200 : lecture ou traitement OK

• 201 : création OK

• 404 : aucune donnée

• 401 : connexion refusée
Lecture d’une API REST (1)
• On commence par créer un ‘provider’, classe
réservée à un traitement qui n’est pas un affichage

• ionic g provider ApiTest
• Tant qu'on y est, on va également créer la page qui
nous servira à afficher la liste des utilisateurs

• ionic g page ListUsers
57
Lecture d’une API REST (2)
• Le provider contient le code de base pour appeler
l’API :

import { Http } from '@angular/http';
export class ApiTest {
baseurl: string;
constructor(public http: Http) {
this.baseurl = ‘https://reqres.in/api';
}
getURL(url)
{
url=this.baseurl + url;
return this.http.get(url).map(res => res.json());
}
58
L’adresse de l’API est
importante car elle doit être
stockée en dur dans le
code
Ce traitement est
asynchrone ; on y reviendra
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
Lecture d’une API REST (3)
• On peut ensuite utiliser le provider dans une page pour
peupler une liste

import {ApiTest} from '../../providers/api-test';
@Component({
providers: [ApiTest]
})
export class UnePage {
users: Array<any>;
constructor(public navCtrl: NavController, public apiTest:ApiTest) {
}
59
toute
variable passée en
entrée du constructeur
est ensuite accessible
en tant qu’attribut
attribut
qui stockera
la liste
Utilisation du
provider
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
Lecture d’une API REST (4)
• On complète ensuite la classe d'une initialisation consistant
à lire les données

ngOnInit() {
this.apiTest.getURL('/users/').subscribe(
data => {
this.users = data.data;
},
err => {
console.log("erreur :"+JSON.stringify(err));
},
() => console.log('Load Complete')
);
}
60
les données lues sont
ensuite stockées dans
l'attribut users
Traitement
asynchrone
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
"data": [
{
"id": 4,
…
},
{
"id": 5,
…
},
…
]
Lecture d’une API REST (5)
• On gère ensuite l’affichage de la liste dans la partie HTML
de la page

• <button> est un élément fixe, mais l'attribut *ngFor va
provoquer sa répétition

<ion-list>
<button ion-item *ngFor="let user of users">
{{user.first_name}}
</button>
</ion-list>
61
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
"data": [
{
"id": 4,
"first_name": "eve",
"last_name": "holt",
"avatar": "…"
},
Rendre les items
de la liste cliquables (1)
• On va maintenant modifier nos <button> pour qu'ils
soient cliquables

• chaque clic lance un appel à la méthode itemTapped(),
en passant en paramètre le user courant

<button ion-item *ngFor="let user of users" 

(click)="itemTapped($event, user)">
…
</button>
62
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
Rendre les items
de la liste cliquables (2)
• Un clic sur un élément provoquera l’appel à une
méthode de la classe

itemTapped(event, user) {
this.navCtrl.push(UserPage, {
param_user: user
});
}
63
C'est l'objet user
complet qui est envoyé en
paramètre d’entrée de la
page UserPage
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
Rendre les items
de la liste cliquables (3)
• On va ensuite créer une page User

• Cette page contiendra le code nécessaire pour récupérer
le paramètre qu'on lui a fourni

user:any;
constructor(public navCtrl:NavController, public navParams: NavParams)
{
this.user = navParams.get('param_user');
}
64
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
/pages/user/user.ts
/pages/user/user.html
Rendre les items
de la liste cliquables (4)
• La page va ensuite pouvoir afficher le contenu à partir de
l'objet user qu'on a reçu en paramètre, sans
rechargement nécessaire

<ion-card>
<ion-card-content>
<ion-card-title>
Bonjour, {{user.first_name}} {{user.last_name}} !
</ion-card-title>
</ion-card-content>
</ion-card>
65
/providers/api-test.ts
/pages/list-users/list-users.ts
/pages/list-users/list-users.html
/pages/user/user.ts
/pages/user/user.html
Schéma récapitulatif
Serveur
Héberge des API
REST
HTTPapi-test.ts
provider de
lecture de l'API
list-users.ts
• Appel du
provider
• Stockage
dans
l'attribut
'users'
list-users.html
boucle sur
'users'
user.ts
Stockage de
'user' en
attribut
data
param_user : useritemTapped(user)
user.html
affiche 'user'
Créer un traitement
asynchrone
• Contrairement à ce qui se passe avec un
développement web classique, tout dans Ionic/
Angular fonctionne de manière asynchrone :

• On commence par afficher la page

• On s'occupe ensuite d'afficher les éléments
dynamiques au fur et à mesure de leur récupération

• L'objectif est de fluidifier au maximum la réactivité de
l'application
67
Subscribe
• Les appels aux API REST étaient asynchrones :

this.apiTest.getURL('/users/').subscribe(
data => {
this.users = data;
},
err => {
},
);
}
68
Traitement
asynchrone
N'est exécuté
qu'une fois la
lecture achevée
<ion-card *ngFor="let user of users">
…
</ion-card> L'affichage
est lui aussi
asynchrone
Créer ses propres
traitements asynchrones
getMedia(id)
{
return Observable.create(s => {
// traitement prenant du temps
var retour = /* retour préparé */;
s.next(retour);
s.complete();
},
err => {
console.log(JSON.stringify(err));
},
() => console.log('getMedia terminé')
);
}
69
this.apiTest.getMedia(id).subscribe(
data => {
this.users = data;
},
err => {
},
);
}
s.next() permet
d'envoyer des données en
retour de getMedia()
Afficher du contenu HTML
• Dans certains cas (par exemple en récupérant un
article de Wordpress), l'API peut vous retourner du
code HTML

• Pour que ce code soit interprété (et non pas
affiché), il faut utiliser une balise particulière :

<p [innerHTML]="user.descriptif"></p>
70
Pas besoin de
mettre des accolades
pour préciser qu'il s'agit
d'un attribut
Gestion des styles
• Le look des pages s'effectue via des styles CSS
situés :

• de manière globale, dans /src/app/app.scss

• pour chacune des pages, dans nom-page.scss
• Il est possible de lier un thème à son application
71
SCSS
• Il s'agit d'une déclinaison du langage CSS, avec
quelques rajouts bien utiles

• Chaque code SCSS est ensuite transformé en CSS

• Par exemple :
72
table.hl {
margin: 2em 0;
td.ln {
text-align: right;
}
}
li {
font: {
family: serif;
weight: bold;
size: 1.3em;
}
}
table.hl {
margin: 2em 0;
}
table.hl td.ln {
text-align: right;
}
li {
font-family: serif;
font-weight: bold;
font-size: 1.3em;
}
L'héritage en SCSS
• Permet de simplifier l'écriture de certains blocs
73
.error
border: 1px #f00
background: #fdd
.error.intrusion
font-size: 1.3em
font-weight: bold
.badError
@extend .error
border-width: 3px
.error, .badError {
border: 1px #f00;
background: #fdd;
}
.error.intrusion,
.badError.intrusion {
font-size: 1.3em;
font-weight: bold;
}
.badError {
border-width: 3px;
}
Insertion d'animations
• On peut utiliser la bibliothèque animate.css

https://daneden.github.io/animate.css/

1. Téléchargement et stockage dans 

/src/assets/css

2. Chargement dans /src/index.html

<link href="assets/css/animate.css" rel="stylesheet">
3. Utilisation dans le code HTML des pages. Ex :

<ion-card class="animated fadeInLeftBig">
74
Plugins natifs
• Ces plugins sont la raison d'être même d'Ionic :
permettre de tirer le meilleur du hardware des
smartphones tout en restant dans un contexte web

• C'est Cordova qui est en charge de la partie native,
par toute une série de plugins développés dans les
langages natifs des environnements (iOS, Android)

• Liste complète des plugins (plus de 2000 !)
disponibles à l'adresse suivante :

https://cordova.apache.org/plugins/
75
Prise de photo
• On utilise le plugin natif cordova-plugin-camera :

ionic plugin add cordova-plugin-camera
• La page dédiée à la prise de photo sera ainsi constituée :

import {Camera} from 'ionic-native';
export class CapturePicPage {
public base64Image: string;
}
• L'attribut base64Image permettra de stocker la dernière photo prise
sous forme binaire

• On pourra bien sûr stocker ensuite cette photo en base de
données
76
Interface de prise de photo
• Dans cet exemple minimaliste, on se contente d'un bouton
pour lancer le capteur, et pour afficher la dernière photo
prise :

<ion-card>
<ion-card-content>
<h1>Prise de photo</h1>
<button ion-button (click)="takePicture()">Prendre une photo</button>
<h2>Dernière photo prise :</h2>
<img *ngIf="base64Image" [src]="base64Image" />
</ion-card-content>
</ion-card>
77
Le "src" est ici à
prendre au sens large
(donnée binaire, pas nom
de fichier)
La balise ne sera
présente que si l'attribut
base64Image n'est pas
vide
Méthode de prise de photo
• Dernière étape : créer la méthode takePicture() qui
sera appelée lors du clic sur le bouton :

takePicture(){
Camera.getPicture({
destinationType: Camera.DestinationType.DATA_URL,
targetWidth: 1000,
targetHeight: 1000
}).then((data) => {
this.base64Image = "data:image/jpeg;base64," + data;
}, (err) => {
console.log(err);
});
}
78
Stockage local de données
• On commence par créer un Provider qui centralisera
l'accès aux données. Il aura pour rôle :

• de stocker de manière centralisée les principales
données de l'application pendant son fonctionnement

• d'accéder à la base de données pour stocker des
données de manière persistante

• Attention, pour écrire les tests permettant de déterminer
la source des données, il faudra en permanence penser
aux traitements asynchrones
79
Créer un provider global
• Pour stocker des données qui seront accessibles tout au long
du fonctionnement de l'application :

• Créer un provider doté d'attributs dans lesquels on stocke
les données

• Déclarer ce provider directement dans le bloc @NgModule
de app.module.ts
• On pourra ensuite créer dans ce même provider des
méthodes d'accès à la base de données, pour apporter une
pérennité aux données au delà de la présence en mémoire
de l'application
Mettre en priorité les moteurs les plus performants
80
Différents styles de
stockage
• Il existe plusieurs moteurs de stockage de données pour
une app Ionic :

• SQLite (mini-SGBD embarqué sous forme de plugin
natif)

• IndexedDB (mini-SGBD conçu par Mozilla)

• WebSQL (API vers un SGBD porté sur Chrome et Safari)

• localstorage (stockage de données key->value
standardisé dans HTML5)
81
Installation
• Le seul élément essentiel est le module gérant le
frontal d'accès au stockage de données

npm install --save @ionic/storage
• Vous pouvez également installer le plugin (natif)
SQLite

cordova plugin add cordova-sqlite-storage --save
82
Configuration du module
• Tout se passe dans app.module.ts

import { IonicStorageModule } from '@ionic/storage';
…
@NgModule({
declarations: ...,
imports: [
IonicStorageModule.forRoot({
name: '__mydb',
driverOrder: ['indexeddb', 'sqlite', 'websql','localstorage']
})
],
83
Mettre en priorité les
moteurs les plus
performants
Utilisation de base
• Le principe universel est celui dit "key/value" : on stocke
une valeur, indexée par une clé

import { Storage } from '@ionic/storage';
…
constructor(……, public storage:Storage) {
this.storage.ready().then(() => {
// stockage d'une valeur
this.storage.set('name', 'Jean David');
//Lecture d'une valeur par sa clé
this.storage.get('session_ID').then((val) => {
console.log('votre ID session :', val);
})
});
84
Key Value
name Jean David
client 1
session_ID
enGHumY%2C-2De-F-
TDzNHVmE%2ChY5
Utilisation avec SQL
• Lorsque le moteur de base de données le permet, on peut
utiliser des requêtes SQL (simplifiées) pour structurer de
manière plus complexe ses données

import {SqlStorage, Storage} from '@ionic/storage';
export class HomePage {
private storage: Storage;
public constructor() {
this.storage = new Storage(SqlStorage);
this.storage.query("CREATE TABLE IF NOT EXISTS users
(id INTEGER PRIMARY KEY AUTOINCREMENT,
first_name TEXT,
last_name TEXT)");
}
85
Insertion de données
avec SQL
• Les traitements sont asynchrones

this.storage.query("INSERT INTO users (first_name,
last_name) VALUES (?, ?)", ["JD", "Olek"]).then((data) => {
console.log("ok!");
}, (error) => {
console.log(error);
});
86
Cette partie n'est
exécutée qu'une fois
l'insertion terminée
Lecture de données
avec SQL
• Là aussi, la lecture est asynchrone

let liste:Array<Object>;
this.storage.query("SELECT * FROM users").then((data) => {
if(data.res.rows.length > 0) {
liste = [];
for(let i = 0; i < data.res.rows.length; i++) {
liste.push({
"id": data.res.rows.item(i).id,
"first_name": data.res.rows.item(i).first_name,
"last_name": data.res.rows.item(i).last_name,
});
}
}
}, (error) => {
console.log(error);
});
87
Géolocalisation
• Une fois encore, on va utiliser un plugin natif

ionic plugin add cordova-plugin-geolocation
• La récupération des coordonnées est un simple traitement asynchrone

import { Geolocation } from 'ionic-native';
export class MaPage {
latitude : number;
longitude : number;
…
ionViewDidLoad() {
Geolocation.getCurrentPosition().then((position) => {
this.latitude=position.coords.latitude;
this.longitude=position.coords.longitude;
}
}
 
88
On peut aussi
imaginer faire plutôt un
provider pour gérer la
localisation
Géoloc et Google Maps
• Cette partie va être l'occasion de montrer l'usage
d'une librairie Javascript directement au sein d'une
app Ionic

• Le chargement de la librairie Google Maps se fait
directement dans le fichier index.html :

<script src="http://maps.google.com/maps/api/js"></script>
89
En production, il faut
rajouter ?key=MACLE en
mentionnant une clé
d'utilisateur
de Google Maps
Affichage de la map
• L'affichage sera une simple zone avec un marqueur #map qui
permettra au traitement de remplir plus tard cette zone avec
la carte

<ion-content>
<div #map id="carte"></div>
</ion-content>
• Du côté du fichier .ts, on utilise ViewChild et ElementRef
pour pouvoir manipuler ce bloc #map plus tard

import { Component, ViewChild, ElementRef } from '@angular/core';
declare var google;
export class HomePage {
@ViewChild('map') mapElement: ElementRef;
map: any;
90
.scroll-content {
height: 100%
}
#carte {
width: 100%;
height: 100%;
}
Le CSS permettra de
s'assurer du bon
affichage de la carte
Génération de la map
• Il nous reste encore à afficher la map. On le fait à la
suite de la géolocalisation

ionViewDidLoad(){
…
let mapOptions = {
center: new google.maps.LatLng(this.latitude,this.longitude),
zoom: 15,
mapTypeId: google.maps.MapTypeId.ROADMAP
}
this.map = new google.maps.Map(
this.mapElement.nativeElement, mapOptions);
}
91
Coordonnées
précédemment obtenues
par le plugin de
géolocalisation
Pointage vers
l'emplacement #map de la
vue

Contenu connexe

Tendances

Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JS
Abdoulaye Dieng
 
Support de Cours JSF2 Première partie Intégration avec Spring
Support de Cours JSF2 Première partie Intégration avec SpringSupport de Cours JSF2 Première partie Intégration avec Spring
Support de Cours JSF2 Première partie Intégration avec Spring
ENSET, Université Hassan II Casablanca
 
Android-Tp5 : web services
Android-Tp5 : web servicesAndroid-Tp5 : web services
Android-Tp5 : web services
Lilia Sfaxi
 
Presentation SOAP
 Presentation SOAP Presentation SOAP
Presentation SOAP
litayem bechir
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
Youness Boukouchi
 
Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
ENSET, Université Hassan II Casablanca
 
Support JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.YoussfiSupport JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.Youssfi
ENSET, Université Hassan II Casablanca
 
Android-Tp1: éléments graphiques de base et intents
Android-Tp1: éléments graphiques de base et intentsAndroid-Tp1: éléments graphiques de base et intents
Android-Tp1: éléments graphiques de base et intents
Lilia Sfaxi
 
Ouzamou mohamed cv
Ouzamou mohamed cvOuzamou mohamed cv
Ouzamou mohamed cv
Mohamed OUZAMOU
 
Application web php5 html5 css3 bootstrap
Application web php5 html5 css3 bootstrapApplication web php5 html5 css3 bootstrap
Application web php5 html5 css3 bootstrap
Bassem ABCHA
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
ENSET, Université Hassan II Casablanca
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
ENSET, Université Hassan II Casablanca
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
ENSET, Université Hassan II Casablanca
 
Cours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategyCours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategy
ENSET, Université Hassan II Casablanca
 
Web services SOAP et REST
Web services  SOAP et RESTWeb services  SOAP et REST
Web services SOAP et REST
RadhoueneRouached
 
Panorama des Technologies mobiles
Panorama des Technologies mobilesPanorama des Technologies mobiles
Panorama des Technologies mobiles
Abdoulaye Dieng
 
Introduction_Reseau.ppt
Introduction_Reseau.pptIntroduction_Reseau.ppt
Introduction_Reseau.ppt
AmalHadri2
 
Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce  Basé sur Spring IOC MVC Security JPA HibernateSite JEE de ECommerce  Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
ENSET, Université Hassan II Casablanca
 
Python et son intégration avec Odoo
Python et son intégration avec OdooPython et son intégration avec Odoo
Python et son intégration avec Odoo
Hassan WAHSISS
 
Support de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfiSupport de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfi
ENSET, Université Hassan II Casablanca
 

Tendances (20)

Introduction à React JS
Introduction à React JSIntroduction à React JS
Introduction à React JS
 
Support de Cours JSF2 Première partie Intégration avec Spring
Support de Cours JSF2 Première partie Intégration avec SpringSupport de Cours JSF2 Première partie Intégration avec Spring
Support de Cours JSF2 Première partie Intégration avec Spring
 
Android-Tp5 : web services
Android-Tp5 : web servicesAndroid-Tp5 : web services
Android-Tp5 : web services
 
Presentation SOAP
 Presentation SOAP Presentation SOAP
Presentation SOAP
 
Appalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSPAppalications JEE avec Servlet/JSP
Appalications JEE avec Servlet/JSP
 
Support JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVCSupport JEE Spring Inversion de Controle IOC et Spring MVC
Support JEE Spring Inversion de Controle IOC et Spring MVC
 
Support JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.YoussfiSupport JEE Servlet Jsp MVC M.Youssfi
Support JEE Servlet Jsp MVC M.Youssfi
 
Android-Tp1: éléments graphiques de base et intents
Android-Tp1: éléments graphiques de base et intentsAndroid-Tp1: éléments graphiques de base et intents
Android-Tp1: éléments graphiques de base et intents
 
Ouzamou mohamed cv
Ouzamou mohamed cvOuzamou mohamed cv
Ouzamou mohamed cv
 
Application web php5 html5 css3 bootstrap
Application web php5 html5 css3 bootstrapApplication web php5 html5 css3 bootstrap
Application web php5 html5 css3 bootstrap
 
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfiJava entreprise edition et industrialisation du génie logiciel par m.youssfi
Java entreprise edition et industrialisation du génie logiciel par m.youssfi
 
Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)Sécurité des Applications Web avec Json Web Token (JWT)
Sécurité des Applications Web avec Json Web Token (JWT)
 
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...Mohamed youssfi support architectures logicielles distribuées basées sue les ...
Mohamed youssfi support architectures logicielles distribuées basées sue les ...
 
Cours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategyCours design pattern m youssfi partie 1 introduction et pattern strategy
Cours design pattern m youssfi partie 1 introduction et pattern strategy
 
Web services SOAP et REST
Web services  SOAP et RESTWeb services  SOAP et REST
Web services SOAP et REST
 
Panorama des Technologies mobiles
Panorama des Technologies mobilesPanorama des Technologies mobiles
Panorama des Technologies mobiles
 
Introduction_Reseau.ppt
Introduction_Reseau.pptIntroduction_Reseau.ppt
Introduction_Reseau.ppt
 
Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce  Basé sur Spring IOC MVC Security JPA HibernateSite JEE de ECommerce  Basé sur Spring IOC MVC Security JPA Hibernate
Site JEE de ECommerce Basé sur Spring IOC MVC Security JPA Hibernate
 
Python et son intégration avec Odoo
Python et son intégration avec OdooPython et son intégration avec Odoo
Python et son intégration avec Odoo
 
Support de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfiSupport de cours entrepise java beans ejb m.youssfi
Support de cours entrepise java beans ejb m.youssfi
 

Similaire à Développement web mobile avec IONIC 2

Tech conf1 développement_natif_applications_mobiles
Tech conf1 développement_natif_applications_mobilesTech conf1 développement_natif_applications_mobiles
Tech conf1 développement_natif_applications_mobiles
TelecomValley
 
Passage aux applications mobiles
Passage aux applications mobilesPassage aux applications mobiles
Passage aux applications mobiles
neuros
 
Strategies et developpements mobiles multi-plates-formes.
Strategies et developpements mobiles multi-plates-formes.Strategies et developpements mobiles multi-plates-formes.
Strategies et developpements mobiles multi-plates-formes.
DocDoku
 
Ionic
IonicIonic
Tech Conf n°1 - Développement natif d'applications mobiles
Tech Conf n°1 - Développement natif d'applications mobilesTech Conf n°1 - Développement natif d'applications mobiles
Tech Conf n°1 - Développement natif d'applications mobiles
Michael Laguerre
 
Panorama des solutions mobile hybrides
Panorama des solutions mobile hybridesPanorama des solutions mobile hybrides
Panorama des solutions mobile hybrides
ekino
 
Développement mobile cross-plateform
Développement mobile cross-plateformDéveloppement mobile cross-plateform
Développement mobile cross-plateform
Stefan Cosquer
 
Rex ionic
Rex ionicRex ionic
Rex ionic
Rémi Flipo
 
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKit
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKitConstruire une Application Mobile en 30 minutes avec le plugin WP-AppKit
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKit
uncatcrea
 
Apple - WWDC 2018
Apple - WWDC 2018Apple - WWDC 2018
Apple - WWDC 2018
Maxime Eglem
 
Gtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogyGtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogySacha Leprêtre
 
L’environnement du développement mobile iOS & Android
L’environnement du développement mobile iOS & AndroidL’environnement du développement mobile iOS & Android
L’environnement du développement mobile iOS & Android
Chris Saez
 
Développement Windows 8 METRO App
Développement Windows 8 METRO AppDéveloppement Windows 8 METRO App
Développement Windows 8 METRO App
Clément Hallet
 
Introduction à meteor
Introduction à meteorIntroduction à meteor
Introduction à meteor
Fabian Vilers
 
Construire une PWA connectée à WordPress
Construire une PWA connectée à WordPressConstruire une PWA connectée à WordPress
Construire une PWA connectée à WordPress
Benjamin LUPU
 
jQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-sidejQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-side
maru.maru
 
MUG Strasbourg - Développement d'une Universal Windows Apps
MUG Strasbourg - Développement d'une Universal Windows AppsMUG Strasbourg - Développement d'une Universal Windows Apps
MUG Strasbourg - Développement d'une Universal Windows Apps
mugstrasbourg
 
Devoxx France 2015 - Introduction à Ionic framework
Devoxx France 2015 - Introduction à Ionic frameworkDevoxx France 2015 - Introduction à Ionic framework
Devoxx France 2015 - Introduction à Ionic framework
Stéphanie Moallic
 

Similaire à Développement web mobile avec IONIC 2 (20)

Tech conf1 développement_natif_applications_mobiles
Tech conf1 développement_natif_applications_mobilesTech conf1 développement_natif_applications_mobiles
Tech conf1 développement_natif_applications_mobiles
 
Passage aux applications mobiles
Passage aux applications mobilesPassage aux applications mobiles
Passage aux applications mobiles
 
Strategies et developpements mobiles multi-plates-formes.
Strategies et developpements mobiles multi-plates-formes.Strategies et developpements mobiles multi-plates-formes.
Strategies et developpements mobiles multi-plates-formes.
 
Ionic
IonicIonic
Ionic
 
Tech Conf n°1 - Développement natif d'applications mobiles
Tech Conf n°1 - Développement natif d'applications mobilesTech Conf n°1 - Développement natif d'applications mobiles
Tech Conf n°1 - Développement natif d'applications mobiles
 
Panorama des solutions mobile hybrides
Panorama des solutions mobile hybridesPanorama des solutions mobile hybrides
Panorama des solutions mobile hybrides
 
Développement mobile cross-plateform
Développement mobile cross-plateformDéveloppement mobile cross-plateform
Développement mobile cross-plateform
 
Rex ionic
Rex ionicRex ionic
Rex ionic
 
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKit
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKitConstruire une Application Mobile en 30 minutes avec le plugin WP-AppKit
Construire une Application Mobile en 30 minutes avec le plugin WP-AppKit
 
Apple - WWDC 2018
Apple - WWDC 2018Apple - WWDC 2018
Apple - WWDC 2018
 
Gtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogyGtug2 Mobile app with web technlogy
Gtug2 Mobile app with web technlogy
 
L’environnement du développement mobile iOS & Android
L’environnement du développement mobile iOS & AndroidL’environnement du développement mobile iOS & Android
L’environnement du développement mobile iOS & Android
 
Développement Windows 8 METRO App
Développement Windows 8 METRO AppDéveloppement Windows 8 METRO App
Développement Windows 8 METRO App
 
Meetup sencha
Meetup senchaMeetup sencha
Meetup sencha
 
Introduction à meteor
Introduction à meteorIntroduction à meteor
Introduction à meteor
 
Construire une PWA connectée à WordPress
Construire une PWA connectée à WordPressConstruire une PWA connectée à WordPress
Construire une PWA connectée à WordPress
 
jQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-sidejQuery mobile / PhoneGap : contenus dynamiques client-side
jQuery mobile / PhoneGap : contenus dynamiques client-side
 
MUG Strasbourg - Développement d'une Universal Windows Apps
MUG Strasbourg - Développement d'une Universal Windows AppsMUG Strasbourg - Développement d'une Universal Windows Apps
MUG Strasbourg - Développement d'une Universal Windows Apps
 
Devoxx France 2015 - Introduction à Ionic framework
Devoxx France 2015 - Introduction à Ionic frameworkDevoxx France 2015 - Introduction à Ionic framework
Devoxx France 2015 - Introduction à Ionic framework
 
Android
AndroidAndroid
Android
 

Plus de Jean David Olekhnovitch

Designs Patterns
Designs PatternsDesigns Patterns
Designs Patterns
Jean David Olekhnovitch
 
Python
PythonPython
Internet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applicationsInternet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applications
Jean David Olekhnovitch
 
Agilité et Entreprise libérée
Agilité et Entreprise libéréeAgilité et Entreprise libérée
Agilité et Entreprise libérée
Jean David Olekhnovitch
 
Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?
Jean David Olekhnovitch
 
JAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de donnéesJAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de données
Jean David Olekhnovitch
 
Java - implémentation des concepts objets
Java - implémentation des concepts objetsJava - implémentation des concepts objets
Java - implémentation des concepts objetsJean David Olekhnovitch
 
Java - notions de bases pour développeur
Java - notions de bases pour développeurJava - notions de bases pour développeur
Java - notions de bases pour développeurJean David Olekhnovitch
 
Internet mobile
Internet mobileInternet mobile
Internet mobile
Jean David Olekhnovitch
 
Ecommerce
EcommerceEcommerce
Genielogiciel
GenielogicielGenielogiciel

Plus de Jean David Olekhnovitch (12)

Designs Patterns
Designs PatternsDesigns Patterns
Designs Patterns
 
Python
PythonPython
Python
 
Internet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applicationsInternet mobile : conception de sites et d'applications
Internet mobile : conception de sites et d'applications
 
Agilité et Entreprise libérée
Agilité et Entreprise libéréeAgilité et Entreprise libérée
Agilité et Entreprise libérée
 
Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?Télétravail et égilité : un mariage impossible ?
Télétravail et égilité : un mariage impossible ?
 
JAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de donnéesJAVA, JDBC et liaison base de données
JAVA, JDBC et liaison base de données
 
Java - implémentation des concepts objets
Java - implémentation des concepts objetsJava - implémentation des concepts objets
Java - implémentation des concepts objets
 
Java - notions de bases pour développeur
Java - notions de bases pour développeurJava - notions de bases pour développeur
Java - notions de bases pour développeur
 
Internet mobile
Internet mobileInternet mobile
Internet mobile
 
Ecommerce
EcommerceEcommerce
Ecommerce
 
Genielogiciel
GenielogicielGenielogiciel
Genielogiciel
 
Plan d'action WAI
Plan d'action WAIPlan d'action WAI
Plan d'action WAI
 

Développement web mobile avec IONIC 2

  • 1. Développement Mobile Web 
 avec IONIC2 Version du 29/03/2017 Jean David Olekhnovitch 📧 jd@olek.fr @gidehault
  • 2. Web et mobile : deux mondes à part • Le web est basé depuis la fin des années 90 sur un mode orienté serveur : • Un serveur HTTP qui centralise tous les traitements • Des clients HTML/CSS qui affichent passivement l’information • De multiples tentatives existent pour ‘dynamiser’ le côté client, Javascript en tête • Un handicap : ça rappelle furieusement le modèle mainframe/ client texte des années 60/70 • Un souhait : préserver un standard ouvert 2
  • 3. Web et mobile : deux mondes à part • Le mobile s’appuie sur des outils de développements plus sophistiqués, mais dédiés à des plateformes incompatibles entre elles 3 Android - Langage Java - Environnement propriétaire Google, sur base Linux - Développement Android Studio - Distribution : Google Play iOS - Langage Swift - Environnement propriétaire Apple, sur base NetBSD - Développement XCode - Distribution : App Store FirefoxOS Windows Phone Blackberry Ubuntu Tizen …
  • 4.
  • 5. Mais la mixité subsiste • D’un côté, il est possible de faire tourner des choses assez évoluées dans le navigateur de son téléphone • De l’autre, il est aujourd’hui possible d’accéder à des fonctions ‘natives’ depuis son navigateur 5
  • 6. 1 - Historiquement : les "sites mobiles" • A l'époque des premiers smartphones, il était nécessaire de faire une version spécifique des sites Internet pour visualisation sur téléphone mobile 6 Avantages ‣ version légère et bien adaptée aux smartphones peu performants ‣ facilité de développement Inconvénients ‣ nécessité de gérer deux versions en parallèle ‣ aucune exploitation des possibilités natives des téléphones
  • 7. 2 - Vers une version unique des sites web : le responsive design • Les possibilités d'élasticité (grille fluide) et d'adaptation aux devices (media queries) des feuilles de style CSS permettent de maintenir une version unique des sites web tout en s'adaptant au format d'affichage 7 Avantages ‣ adaptation relativement simple (que des hacks CSS) ‣ une seule version des sites web à maintenir Inconvénients ‣ aucune exploitation des possibilités natives des téléphones
  • 8. 3 - Un pas vers les fonctions natives : HTML5 • La version HTML5 propose, de manière plus ou moins aboutie, la possibilité d'accéder à certaines fonctions natives depuis son navigateur web 8 Avantages ‣ possibilité de cumuler avec les capacités de responsive design ‣ fonctions accessibles en quelques balises Inconvénients ‣ toutes les fonctions ne sont pas présentes ‣ compatibilité aléatoire suivant les navigateurs
  • 9. Du HTML à l'app mobile : un chemin semé d'embuches 9 Site HTML/ CSS Déclinaison site mobile Site Responsive Site HTML5 App mobile native App hybride web/mobile ? AppsSites Progressive Webapps
  • 10. L’enjeu des fonctions natives • Stockage offline • Géolocalisation • Gestuelles tactiles • Bluetooth • Accéléromètre, boussole… • Notifications • Caméra… 10
  • 11. La barrière des appstore • Google et Apple ont fait le choix du point d'entrée unique vers l'application : l'app store (ou playstore) • Pour diverses raisons de contrôle qualité, de sécurité… et parfois de censure • Cette barrière impose des critères techniques nombreux et peu simples à franchir 11
  • 12. 1ères solutions : Apache Cordova/Adobe PhoneGap • Idée : proposer des passerelles entre les fonctions natives, et des pages conçues en HTML/CSS • Naissance du concept d’Application Hybride • Aujourd’hui intégralement en opensource et géré par l’Apache Foundation 12
  • 13. Limitations de Cordova • Ne propose pas de solution pour l’interface utilisateur (gestuelles tactiles, etc…) • La publication vers les stores Google/Apple reste complexe • A voir plus comme une série de librairies que comme un framework a part entière 13
  • 14. Surcouche et structuration: la solution d'un framework • Idée : compléter la philosophie (et les briques techniques) de Cordova par un véritable framework capable de : • faciliter le développement • industrialiser la publication sur les stores • donner la possibilité de créer des modules optionnels • ‘casser’ la logique de page au sens HTTP du terme 14
  • 15. Côté Facebook : React • Framework développé en interne • Destiné au développement des applications Facebook avant tout • Essentiellement côté « front » • Basé sur Javascript • Fait appel à des composants natifs autant que possible 15
  • 16. Autres frameworks • Onsen UI • Intel XDK • Sencha Touch • Kendo UI • Framework 7 16 • JQuery Mobile • Mobile Angular UI • Famo.us • Monaca • Trigger.IO • Electron (pour applis desktop)
  • 17. Ionic • Créé en 2013 • Repose entièrement sur Cordova pour la partie native • Et sur AngularJS pour la cinématique des pages • v2 sortie fin 2016 • TypeScript remplace Javascript • Angular2 remplace AngularJS 17
  • 18. Angular 2 Architecture d’Ionic2 Apache Cordova Angular 2 Ionic 2 HTML SCSS Typescript NPM NodeJS Moteur HTML/CSS/JS Natif App native Application passerelle vers le monde natif cinématique des écrans framework gestionnaire de paquets environnement de développement affichage in-app via un interpréteur web
  • 19. Installation d’Ionic (1) • Première étape : installation de NodeJS 6 • Inclut NPM (gestionnaire de paquet Javascript) • https://nodejs.org/en/download/ 19
  • 20. Installation d’Ionic (2) • Installation d’Ionic et de Cordova • On se repose sur le gestionnaire de paquets NPM • Tout se passe en ligne de commande… comme ça va être le cas pour toute la suite : • npm install -g ionic cordova 20
  • 21. Première app Ionic • Génération du squelette : • ionic start premierEssai super --v2 • On va dans le répertoire • cd premierEssai • Test dans un navigateur • ionic serve -c --lab 21 Nom du template qui sert de modèle (blank, tabs, sidemenu, tutorial …) ionic peut à la fois créer des apps ionic1 et ionic2 lancement avec console de debug et choix de l’émulateur
  • 22. Visualisation sur un téléphone • Problème : on ne peut pas directement télécharger une app sur un mobile (il faut passer par la validation du constructeur) • Contournement : l'app Ionic View qui permet de visualiser un prototype de son app publié au préalable sur les serveurs Ionic 22
  • 23. Fonctionnement d'Ionic View 23 Poste de travail Serveur Ionic Smartphone App Ionic View ionic upload X synchro in-app interdit Nécessite la création d'un compte sur http://ionic.io Dispo sur AppStore et GooglePlay
  • 24. Installation d’Ionic (3) • Modules supplémentaires • Pour chaque module supplémentaire, là aussi on utilisera npm : • npm install ionic-native --save • Les mises à jour se font elles aussi en ligne de commande : • npm update -g ionic 24 Gestion des dépendances Installation globale
  • 25. Installation d’Ionic (4) • Environnement iOS • Il est obligatoire d’être sur Mac ! • Installation de XCode via le Mac App Store • Déclaration dans ionic : • sudo xcode-select -s /Applications/Xcode.app/ Contents/Developer • sudo npm install -g ios-deploy --unsafe-perm=true -- allow-root 25
  • 26. Installation d’Ionic (5) • Environnement Android • Passe par l’installation de Java (JDK, pas le JRE) : • http://www.oracle.com/technetwork/java/javase/downloads/index.html • Installation d’Android Studio : • https://developer.android.com/studio/index.html • Installation des packages via le Open Android SDK Manager (‘android’ en ligne de commandes) • Android Platform SDK for vXXX • Android SDK build-tools • Android Support Repository • Créer un Android Virtual Device (AVD) pour définir un émulateur type qui servira par la suite 26
  • 27. Génération de l'icône et du splash screen • Les fichiers suivants doivent être stockés dans le répertoire /resources de l'application • icon.png : taille de 192x192 • splash.png : taille de 2208x2208 • La génération de toutes les déclinaisons de ces images se fait ensuite par l'instruction suivante, à lancer avant le build : ionic resources 27
  • 28. Lancement de son application dans un environnement natif • ionic platform add android • ionic platform add ios • ionic build ios • ionic build android 28
  • 29. Préparer un build iOS • Double-cliquer sur • /platforms/ios/MonApp.xcodeproj • Créer sur XCode un « Archive » • Publier ensuite sur le compte (payant !) Developer Apple créé via • https://developer.apple.com • Gestion de la publication sur • https://itunesconnect.apple.com 29
  • 30. Préparer un build Android • Création d’une clé : • keytool -genkey -v -keystore MonApp.keystore -alias MonApp -keyalg RSA -keysize 2048 -validity 10000 • Création du build (fichier .apk) prêt à être importé : • ionic build android --release • Création d’un compte puis publication sur • https://play.google.com/apps/publish/ 30
  • 31. Structuration d’une app ionic • /src : code source de l’application • /resources : stockage de l’icône et du splashscreen • /platforms : version compilée par plateforme • config.xml : fichier principal de configuration de l’app 31
  • 32. Structuration du 
 répertoire /src • /app : fichiers principaux de l’application • /pages : les pages de l’application • /assets : divers fichiers statiques (css, js, images…) • /providers : les ‘providers’ (‘moteurs’) de l’application • /theme : définition d’un thème pour l’application • index.html : fichier de démarrage de l'app 32
  • 33. Création d’une nouvelle page • Création des fichiers : • ionic g page MonEssai • J’obtiens un dossier /src/pages/mon-essai, • et 3 fichiers : • mon-essai.html : interface de la page • mon-essai.scss : style de la page • mon-essai.ts : fonctions de traitement en amont et en aval de la page (avec une classe qui s'appelle MonEssaiPage) 33 MonEssai MonEssaiPage nom de la classe mon-essai nom des fichiers
  • 34. Déclaration d’une nouvelle page • Cette déclaration se fait dans le fichier global 
 /src/app/app.module.ts : import { MonEssaiPage } from '../pages/mon-essai/mon-essai'; • Le nom « MonEssaiPage » doit également être mentionné dans les paragraphes : • ‘declarations’ • ‘entryComponents’ 34
  • 35. Structure d'un fichier .ts • Chaque fichier .ts d'une page (ici : mon-essai.ts) est avant tout une classe import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; @Component({ selector: 'monEssai', templateUrl: 'mon-essai.html' }) export class MonEssaiPage { // attributs // méthodes constructor(public navCtrl: NavController) { } } 35 Import de librairies et fichiers externes utiles Les attributs sont les variables utilisées dans la classe Les méthodes sont des fonctions utilisées dans la classe Le constructeur est la méthode appelée au démarrage de la page Divers paramétrages Fin de la classe
  • 36. Liens entre .ts et .html • Le fichier mon-essai.ts contient une classe (et donc des attributs et méthodes) représentant la partie dynamique de la page • Le fichier mon-essai.html contient la description des éléments visuels de la page • Les deux communiquent intimement par le biais des mécanismes d’Angular 36
  • 37. TS, HTML, et MVC On est en fait ici très proche du pattern MVC bien connu des développeurs d'interface utilisateur • Mais le contrôleur est ici géré de manière transparente par le framework Angular 37 Vue mon-essai.html Contrôleur Ionic/Angular Modèle mon-essai.ts
  • 38. Affichage d’une variable dans la page • Prenons l’exemple d’un attribut de la classe 
 (dans mon-essai.ts) : export class MonEssaiPage {
 unAttribut: string="un contenu"; • On affiche ensuite l'attribut au milieu du code de la page mon-essai.html de la manière suivante : <p>{{unAttribut}}</p> • Nul besoin de préciser le nom de la classe ou de l’instance • On verra plus tard que cette liaison est dynamique, et permet la mise à jour du contenu de cette variable 38
  • 39. Aller d’une page à l’autre (1) • Pour aller à la nouvelle page, on commence par créer un bouton dans le fichier .html de la page principale : <button ion-button>Cliquez ici</button> • On rajoute ensuite une mention '(click)' qui permet d'indiquer le comportement à avoir lors d'un clic sur le bouton <button ion-button (click)="boutonClic()">Cliquez ici</button> 39 Fonction qui sera appelée lors du 'clic'
  • 40. Aller d’une page à l’autre (2) • On crée la fonction correspondante dans le fichier .ts de la page principale: boutonClic() {
 this.navCtrl.push(MonEssaiPage);
 } • Pour fonctionner, ce code a besoin au préalable de deux éléments : • La page MonEssaiPage doit être importée pour être connue import {MonEssaiPage} from '../mon-essai/mon-essai'; • Le contrôleur de navigation ‘navCtrl’ doit être connu et déclaré : import { NavController} from 'ionic-angular'; constructor(public navCtrl: NavController) { 40
  • 41. Schéma récapitulatif Cliquez ici home.html class HomePage { boutonClic() { this.navCtrl.push (MonEssaiPage); } home.ts {{unAttribut}} mon-essai.html mon-essai.ts class MonEssaiPage { unAttribut : string; } Démarrage de l'app
  • 42. Le constructeur d'une classe de page • Ce constructeur a des paramètres d'entrée qui fonctionnent de manière "magique" : il suffit de les mentionner pour qu'ils : • soient renseignés avec des objets déjà initialisés • remplissent un attribut du même nom (rendant l'objet accessible dans toute la classe) • Cette 'magie' est en fait le pattern injection, géré par le framework • Ces providers sont : • Soit des contrôleurs standards d'ionic-angular (ex : NavController) • soit déclarés dans app.module.ts (providers globaux à l'app) • soit dans le bloc @Component de la page 42
  • 43. Afficher des traces dans la console • Lancer ionic serve avec le paramètre -c permet d'avoir une trace de la console dans le terminal, ce qui est bien pratique pour débugger • Vous pouvez n'importe où dans le code afficher des éléments dans la console : console.log("valeur de x :"+x); • Vous pouvez également afficher des structures complexes avec JSON.stringify : console.log("erreur :"+JSON.stringify(err)); 43
  • 44. Composants ionic • ionic2 est fourni avec de très très très nombreux composants, pour gérer à peu près toute l’interface de son app mobile • Nous allons voir sur la suite de ce cours quelques uns de ces composants, mais une bonne idée est de commencer par les découvrir en regardant la page : • http://ionicframework.com/docs/v2/components/ 44
  • 45. Rafraichissement d'une page • Pour proposer un rafraichissement d'une page, on passe par le composant <ion-refresher>, à positionner en tête de son <ion-content> : <ion-refresher (ionRefresh)="doRefresh($event)"> <ion-refresher-content pullingIcon="arrow-dropdown" pullingText="Tirer pour mettre à jour" refreshingSpinner="circles" refreshingText="Mise à jour..."> </ion-refresher-content> </ion-refresher> 45
  • 46. Récupérer la saisie d'un champ de saisie • On commence par créer dans la classe (côté .ts, donc), un attribut nom qui récupérera le contenu nom : string = ""; • Ensuite, dans la page (côté .html), on utilise le component ion-input avec la propriété ngModel qui va permettre de faire le lien avec l'attribut <ion-input [(ngModel)]="nom"></input> 46
  • 47. Créer une barre de navigation (1) • On peut passer par le template ‘tabs’ lors de la création de son projet • Mais il est également possible de construire manuellement sa barre de navigation : • On commence par créer une ‘page’ qui ne contiendra que les données de la barre de navigation : • ionic g page Tabs • On crée ensuite deux pages qui compléteront Home en tant que pages pointées par la barre de navigation (pour l'exemple : Actus, Pratique) 47
  • 48. Créer une barre de navigation (2) • Cette page Tabs contient côté HTML la liste des entrées de la barre : <ion-tabs> <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab> <ion-tab [root]="tab2Root" tabTitle="Actus" tabIcon="actus"></ion-tab> <ion-tab [root]="tab3Root" tabTitle="Pratique" tabIcon="pratique"></ion-tab> </ion-tabs> • Le fichier .ts va permettre de lier à chaque entrée une page : import { HomePage } from '../home/home'; import { ActusPage } from '../actus/actus'; import { PratiquePage } from '../pratique/pratique'; export class TabsPage { tab1Root: any = HomePage; tab2Root: any = ActusPage; tab3Root: any = PratiquePage; 48
  • 49. Créer une barre de navigation (3) • Dernière étape, cette page Tabs doit être déclarée comme étant la page d’entrée de l’application, en remplacement de Home • Cette opération se fait dans le fichier app.components.ts : import { TabsPage } from '../pages/tabs/tabs'; export class MyApp { rootPage = TabsPage; // rootPage = HomePage; // ancienne page d'entrée 49
  • 50. Créer un menu latéral • On peut passer par le template ‘sidemenu’ lors de la création de son projet • Mais il est également possible de construire manuellement son menu 50
  • 51. API REST et JSON • Une API REST est un moyen de faire communiquer un serveur et un client d’une manière souple, simple et légère, en se basant : • Sur le protocole de transfert HTTP (compatible sur tous réseaux, léger, sécurisable) via ses diverses déclinaisons : GET, POST, PUT, DELETE • Sur l’encodage JSON des trames, pour pouvoir transférer tout type de structure de données 51
  • 52. JSON • Ce format est une alternative plus légère à XML pour structurer des données • donnée simple : "name" : "Jean Dupont" • données multiples : "movies": ["titre1", "titre2"] • structure complexe : { "name":"paul rudd", "movies":[ "I Love You Man", "Role Models" ], } 52
  • 53. Exemple d’API REST • Nous allons partir sur l’exemple complet en ligne
 https://reqres.in • Cet exemple permet à la fois de trouver des exemples de fonctionnement pour comprendre ce qu’est une API REST • mais aussi de source pour pouvoir construire ses premiers projets sans se soucier de la partie serveur • NB : le CMS WordPress est depuis sa version 4.7 un bon support pour diffuser facilement des données via une API REST 53
  • 54. Exemple de requête REST simple https://reqres.in/api/users/2 avec la méthode GET permet de récupérer les données du user 2 Données retournées : { "data": { "id": 2, "first_name": "lucille", "last_name": "bluth", "avatar": "https://s3.amazonaws.com/jstein/128.jpg" } } 54 L’id est directement présent dans l’URL
  • 55. Exemple de requête REST de liste • https://reqres.in/api/users/ (sans préciser d’id user) permet de récupérer une liste "page": "1", "per_page": 3, "total": 12, "total_pages": 4, "data": [ { "id": 4, "first_name": "eve", "last_name": "holt", "avatar": "https://s3.amazonaws.com/marcoramires/128.jpg" }, { "id": 5, "first_name": "gob", "last_name": "bluth", "avatar": "https://s3.amazonaws.com/stephenmoon/128.jpg" }, { "id": 6, "first_name": "tracey", "last_name": "bluth", "avatar": "https://s3.amazonaws.com/bigmancho/128.jpg" } ] } 55
  • 56. Méthodes HTTP • Même si ces méthodes sont indépendantes des traitements, on les utilise communément pour les usages suivants dans le cadre d’une API REST : • GET : lecture de données • POST : création de données • PUT : mise à jour de données • DELETE : suppression de données 56 Les codes d'erreur sont également 
 mis à contribution : • 200 : lecture ou traitement OK • 201 : création OK • 404 : aucune donnée • 401 : connexion refusée
  • 57. Lecture d’une API REST (1) • On commence par créer un ‘provider’, classe réservée à un traitement qui n’est pas un affichage • ionic g provider ApiTest • Tant qu'on y est, on va également créer la page qui nous servira à afficher la liste des utilisateurs • ionic g page ListUsers 57
  • 58. Lecture d’une API REST (2) • Le provider contient le code de base pour appeler l’API : import { Http } from '@angular/http'; export class ApiTest { baseurl: string; constructor(public http: Http) { this.baseurl = ‘https://reqres.in/api'; } getURL(url) { url=this.baseurl + url; return this.http.get(url).map(res => res.json()); } 58 L’adresse de l’API est importante car elle doit être stockée en dur dans le code Ce traitement est asynchrone ; on y reviendra /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html
  • 59. Lecture d’une API REST (3) • On peut ensuite utiliser le provider dans une page pour peupler une liste import {ApiTest} from '../../providers/api-test'; @Component({ providers: [ApiTest] }) export class UnePage { users: Array<any>; constructor(public navCtrl: NavController, public apiTest:ApiTest) { } 59 toute variable passée en entrée du constructeur est ensuite accessible en tant qu’attribut attribut qui stockera la liste Utilisation du provider /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html
  • 60. Lecture d’une API REST (4) • On complète ensuite la classe d'une initialisation consistant à lire les données ngOnInit() { this.apiTest.getURL('/users/').subscribe( data => { this.users = data.data; }, err => { console.log("erreur :"+JSON.stringify(err)); }, () => console.log('Load Complete') ); } 60 les données lues sont ensuite stockées dans l'attribut users Traitement asynchrone /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html "data": [ { "id": 4, … }, { "id": 5, … }, … ]
  • 61. Lecture d’une API REST (5) • On gère ensuite l’affichage de la liste dans la partie HTML de la page • <button> est un élément fixe, mais l'attribut *ngFor va provoquer sa répétition <ion-list> <button ion-item *ngFor="let user of users"> {{user.first_name}} </button> </ion-list> 61 /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html "data": [ { "id": 4, "first_name": "eve", "last_name": "holt", "avatar": "…" },
  • 62. Rendre les items de la liste cliquables (1) • On va maintenant modifier nos <button> pour qu'ils soient cliquables • chaque clic lance un appel à la méthode itemTapped(), en passant en paramètre le user courant <button ion-item *ngFor="let user of users" 
 (click)="itemTapped($event, user)"> … </button> 62 /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html
  • 63. Rendre les items de la liste cliquables (2) • Un clic sur un élément provoquera l’appel à une méthode de la classe itemTapped(event, user) { this.navCtrl.push(UserPage, { param_user: user }); } 63 C'est l'objet user complet qui est envoyé en paramètre d’entrée de la page UserPage /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html
  • 64. Rendre les items de la liste cliquables (3) • On va ensuite créer une page User • Cette page contiendra le code nécessaire pour récupérer le paramètre qu'on lui a fourni user:any; constructor(public navCtrl:NavController, public navParams: NavParams) { this.user = navParams.get('param_user'); } 64 /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html /pages/user/user.ts /pages/user/user.html
  • 65. Rendre les items de la liste cliquables (4) • La page va ensuite pouvoir afficher le contenu à partir de l'objet user qu'on a reçu en paramètre, sans rechargement nécessaire <ion-card> <ion-card-content> <ion-card-title> Bonjour, {{user.first_name}} {{user.last_name}} ! </ion-card-title> </ion-card-content> </ion-card> 65 /providers/api-test.ts /pages/list-users/list-users.ts /pages/list-users/list-users.html /pages/user/user.ts /pages/user/user.html
  • 66. Schéma récapitulatif Serveur Héberge des API REST HTTPapi-test.ts provider de lecture de l'API list-users.ts • Appel du provider • Stockage dans l'attribut 'users' list-users.html boucle sur 'users' user.ts Stockage de 'user' en attribut data param_user : useritemTapped(user) user.html affiche 'user'
  • 67. Créer un traitement asynchrone • Contrairement à ce qui se passe avec un développement web classique, tout dans Ionic/ Angular fonctionne de manière asynchrone : • On commence par afficher la page • On s'occupe ensuite d'afficher les éléments dynamiques au fur et à mesure de leur récupération • L'objectif est de fluidifier au maximum la réactivité de l'application 67
  • 68. Subscribe • Les appels aux API REST étaient asynchrones : this.apiTest.getURL('/users/').subscribe( data => { this.users = data; }, err => { }, ); } 68 Traitement asynchrone N'est exécuté qu'une fois la lecture achevée <ion-card *ngFor="let user of users"> … </ion-card> L'affichage est lui aussi asynchrone
  • 69. Créer ses propres traitements asynchrones getMedia(id) { return Observable.create(s => { // traitement prenant du temps var retour = /* retour préparé */; s.next(retour); s.complete(); }, err => { console.log(JSON.stringify(err)); }, () => console.log('getMedia terminé') ); } 69 this.apiTest.getMedia(id).subscribe( data => { this.users = data; }, err => { }, ); } s.next() permet d'envoyer des données en retour de getMedia()
  • 70. Afficher du contenu HTML • Dans certains cas (par exemple en récupérant un article de Wordpress), l'API peut vous retourner du code HTML • Pour que ce code soit interprété (et non pas affiché), il faut utiliser une balise particulière : <p [innerHTML]="user.descriptif"></p> 70 Pas besoin de mettre des accolades pour préciser qu'il s'agit d'un attribut
  • 71. Gestion des styles • Le look des pages s'effectue via des styles CSS situés : • de manière globale, dans /src/app/app.scss • pour chacune des pages, dans nom-page.scss • Il est possible de lier un thème à son application 71
  • 72. SCSS • Il s'agit d'une déclinaison du langage CSS, avec quelques rajouts bien utiles • Chaque code SCSS est ensuite transformé en CSS • Par exemple : 72 table.hl { margin: 2em 0; td.ln { text-align: right; } } li { font: { family: serif; weight: bold; size: 1.3em; } } table.hl { margin: 2em 0; } table.hl td.ln { text-align: right; } li { font-family: serif; font-weight: bold; font-size: 1.3em; }
  • 73. L'héritage en SCSS • Permet de simplifier l'écriture de certains blocs 73 .error border: 1px #f00 background: #fdd .error.intrusion font-size: 1.3em font-weight: bold .badError @extend .error border-width: 3px .error, .badError { border: 1px #f00; background: #fdd; } .error.intrusion, .badError.intrusion { font-size: 1.3em; font-weight: bold; } .badError { border-width: 3px; }
  • 74. Insertion d'animations • On peut utiliser la bibliothèque animate.css
 https://daneden.github.io/animate.css/ 1. Téléchargement et stockage dans 
 /src/assets/css 2. Chargement dans /src/index.html <link href="assets/css/animate.css" rel="stylesheet"> 3. Utilisation dans le code HTML des pages. Ex : <ion-card class="animated fadeInLeftBig"> 74
  • 75. Plugins natifs • Ces plugins sont la raison d'être même d'Ionic : permettre de tirer le meilleur du hardware des smartphones tout en restant dans un contexte web • C'est Cordova qui est en charge de la partie native, par toute une série de plugins développés dans les langages natifs des environnements (iOS, Android) • Liste complète des plugins (plus de 2000 !) disponibles à l'adresse suivante :
 https://cordova.apache.org/plugins/ 75
  • 76. Prise de photo • On utilise le plugin natif cordova-plugin-camera : ionic plugin add cordova-plugin-camera • La page dédiée à la prise de photo sera ainsi constituée : import {Camera} from 'ionic-native'; export class CapturePicPage { public base64Image: string; } • L'attribut base64Image permettra de stocker la dernière photo prise sous forme binaire • On pourra bien sûr stocker ensuite cette photo en base de données 76
  • 77. Interface de prise de photo • Dans cet exemple minimaliste, on se contente d'un bouton pour lancer le capteur, et pour afficher la dernière photo prise : <ion-card> <ion-card-content> <h1>Prise de photo</h1> <button ion-button (click)="takePicture()">Prendre une photo</button> <h2>Dernière photo prise :</h2> <img *ngIf="base64Image" [src]="base64Image" /> </ion-card-content> </ion-card> 77 Le "src" est ici à prendre au sens large (donnée binaire, pas nom de fichier) La balise ne sera présente que si l'attribut base64Image n'est pas vide
  • 78. Méthode de prise de photo • Dernière étape : créer la méthode takePicture() qui sera appelée lors du clic sur le bouton : takePicture(){ Camera.getPicture({ destinationType: Camera.DestinationType.DATA_URL, targetWidth: 1000, targetHeight: 1000 }).then((data) => { this.base64Image = "data:image/jpeg;base64," + data; }, (err) => { console.log(err); }); } 78
  • 79. Stockage local de données • On commence par créer un Provider qui centralisera l'accès aux données. Il aura pour rôle : • de stocker de manière centralisée les principales données de l'application pendant son fonctionnement • d'accéder à la base de données pour stocker des données de manière persistante • Attention, pour écrire les tests permettant de déterminer la source des données, il faudra en permanence penser aux traitements asynchrones 79
  • 80. Créer un provider global • Pour stocker des données qui seront accessibles tout au long du fonctionnement de l'application : • Créer un provider doté d'attributs dans lesquels on stocke les données • Déclarer ce provider directement dans le bloc @NgModule de app.module.ts • On pourra ensuite créer dans ce même provider des méthodes d'accès à la base de données, pour apporter une pérennité aux données au delà de la présence en mémoire de l'application Mettre en priorité les moteurs les plus performants 80
  • 81. Différents styles de stockage • Il existe plusieurs moteurs de stockage de données pour une app Ionic : • SQLite (mini-SGBD embarqué sous forme de plugin natif) • IndexedDB (mini-SGBD conçu par Mozilla) • WebSQL (API vers un SGBD porté sur Chrome et Safari) • localstorage (stockage de données key->value standardisé dans HTML5) 81
  • 82. Installation • Le seul élément essentiel est le module gérant le frontal d'accès au stockage de données npm install --save @ionic/storage • Vous pouvez également installer le plugin (natif) SQLite cordova plugin add cordova-sqlite-storage --save 82
  • 83. Configuration du module • Tout se passe dans app.module.ts import { IonicStorageModule } from '@ionic/storage'; … @NgModule({ declarations: ..., imports: [ IonicStorageModule.forRoot({ name: '__mydb', driverOrder: ['indexeddb', 'sqlite', 'websql','localstorage'] }) ], 83 Mettre en priorité les moteurs les plus performants
  • 84. Utilisation de base • Le principe universel est celui dit "key/value" : on stocke une valeur, indexée par une clé import { Storage } from '@ionic/storage'; … constructor(……, public storage:Storage) { this.storage.ready().then(() => { // stockage d'une valeur this.storage.set('name', 'Jean David'); //Lecture d'une valeur par sa clé this.storage.get('session_ID').then((val) => { console.log('votre ID session :', val); }) }); 84 Key Value name Jean David client 1 session_ID enGHumY%2C-2De-F- TDzNHVmE%2ChY5
  • 85. Utilisation avec SQL • Lorsque le moteur de base de données le permet, on peut utiliser des requêtes SQL (simplifiées) pour structurer de manière plus complexe ses données import {SqlStorage, Storage} from '@ionic/storage'; export class HomePage { private storage: Storage; public constructor() { this.storage = new Storage(SqlStorage); this.storage.query("CREATE TABLE IF NOT EXISTS users (id INTEGER PRIMARY KEY AUTOINCREMENT, first_name TEXT, last_name TEXT)"); } 85
  • 86. Insertion de données avec SQL • Les traitements sont asynchrones this.storage.query("INSERT INTO users (first_name, last_name) VALUES (?, ?)", ["JD", "Olek"]).then((data) => { console.log("ok!"); }, (error) => { console.log(error); }); 86 Cette partie n'est exécutée qu'une fois l'insertion terminée
  • 87. Lecture de données avec SQL • Là aussi, la lecture est asynchrone let liste:Array<Object>; this.storage.query("SELECT * FROM users").then((data) => { if(data.res.rows.length > 0) { liste = []; for(let i = 0; i < data.res.rows.length; i++) { liste.push({ "id": data.res.rows.item(i).id, "first_name": data.res.rows.item(i).first_name, "last_name": data.res.rows.item(i).last_name, }); } } }, (error) => { console.log(error); }); 87
  • 88. Géolocalisation • Une fois encore, on va utiliser un plugin natif ionic plugin add cordova-plugin-geolocation • La récupération des coordonnées est un simple traitement asynchrone import { Geolocation } from 'ionic-native'; export class MaPage { latitude : number; longitude : number; … ionViewDidLoad() { Geolocation.getCurrentPosition().then((position) => { this.latitude=position.coords.latitude; this.longitude=position.coords.longitude; } }   88 On peut aussi imaginer faire plutôt un provider pour gérer la localisation
  • 89. Géoloc et Google Maps • Cette partie va être l'occasion de montrer l'usage d'une librairie Javascript directement au sein d'une app Ionic • Le chargement de la librairie Google Maps se fait directement dans le fichier index.html : <script src="http://maps.google.com/maps/api/js"></script> 89 En production, il faut rajouter ?key=MACLE en mentionnant une clé d'utilisateur de Google Maps
  • 90. Affichage de la map • L'affichage sera une simple zone avec un marqueur #map qui permettra au traitement de remplir plus tard cette zone avec la carte <ion-content> <div #map id="carte"></div> </ion-content> • Du côté du fichier .ts, on utilise ViewChild et ElementRef pour pouvoir manipuler ce bloc #map plus tard import { Component, ViewChild, ElementRef } from '@angular/core'; declare var google; export class HomePage { @ViewChild('map') mapElement: ElementRef; map: any; 90 .scroll-content { height: 100% } #carte { width: 100%; height: 100%; } Le CSS permettra de s'assurer du bon affichage de la carte
  • 91. Génération de la map • Il nous reste encore à afficher la map. On le fait à la suite de la géolocalisation ionViewDidLoad(){ … let mapOptions = { center: new google.maps.LatLng(this.latitude,this.longitude), zoom: 15, mapTypeId: google.maps.MapTypeId.ROADMAP } this.map = new google.maps.Map( this.mapElement.nativeElement, mapOptions); } 91 Coordonnées précédemment obtenues par le plugin de géolocalisation Pointage vers l'emplacement #map de la vue