đŸ 2.4 Persistance et scĂ©narios offline
Module 335 â RĂ©aliser une application pour mobile
đŻ Objectif d'apprentissage
Ă la fin de ce chapitre, vous serez capables de :
- Comprendre les différentes formes de persistance locale sur mobile
- Distinguer bases de donnĂ©es locales, stockage clĂ©âvaleur et stockage de fichiers
- Expliquer le fonctionnement des scénarios offline et du cache local
- Gérer les erreurs réseau, la synchronisation et la résilience d'une application
đ€ 2.4.1 Introduction : pourquoi la persistance ?
Une application mobile nâest pas toujours connectĂ©e Ă Internet :
- tunnels
- bĂątiments
- zones rurales
- métro
- mode avion
Pourtant, les utilisateurs sâattendent Ă ce quâelle continue de fonctionner, mĂȘme hors ligne.
2.4.1 Persistance : définition
La persistance = capacitĂ© dâune application Ă stocker des donnĂ©es localement sur lâappareil, afin quâelles restent disponibles :
- mĂȘme sans rĂ©seau
- mĂȘme aprĂšs fermeture de lâapp
Exemples de données persistées :
- Préférences utilisateur (langue, thÚme sombre)
- Session de connexion
- Notes, listes, messages, documents
- Cache de donnĂ©es venant dâune API (ex. dernier rapport mĂ©tĂ©o)
2.4.1 Trois briques principales
La gestion du mode offline repose sur 3 briques :
- Stockage lĂ©ger (clĂ©âvaleur)
- Base de données locale (SQLite, Realm, CoreData, etc.)
- Synchronisation entre local et serveur quand la connexion revient
2.4.1 Exemple â Application de notes
Une application de notes doit permettre :
- dâajouter / modifier / supprimer des notes mĂȘme hors ligne
- puis de synchroniser ces notes avec le cloud
- dĂšs que la connexion revient
đŻ Objectif du chapitre :
Comprendre les solutions de stockage et comment assurer le offline sans frustrer lâutilisateur.
đ 2.4.2 Stockage clĂ©âvaleur â Principe
Le stockage clĂ©âvaleur = forme de persistance la plus simple.
On enregistre de petites infos sous forme :
clĂ© â valeur
Comme un dictionnaire.
2.4.2 Stockage clĂ©âvaleur â Ă quoi ça sert ?
-
Préférences utilisateur
- thĂšme sombre / clair
- langue
- notifications activées
-
Petits états internes
- derniÚre page visitée
- tutoriel déjà vu
-
Tokens dâauthentification
- JWT
- OAuth
-
ParamĂštres de configuration
â ïž Pas adaptĂ© aux donnĂ©es volumineuses (listes, historiques, gros objetsâŠ).
2.4.2 Outils selon la plateforme
| Plateforme | Outil | Particularités |
|---|---|---|
| Android | SharedPreferences |
Simple, rapide, non chiffré |
| iOS | UserDefaults |
ParamĂštres internes de lâapp |
| Ionic / Capacitor | Preferences |
API JS â natif unifiĂ©e iOS/Android |
| Flutter | shared_preferences |
Stockage léger persistant |
2.4.2 Exemple â Capacitor Preferences
import { Preferences } from '@capacitor/preferences';
await Preferences.set({
key: 'theme',
value: 'dark',
});
Ici, on mĂ©morise le thĂšme choisi par lâutilisateur.
2.4.2 Bonnes pratiques â ClĂ©âvaleur
- Ne jamais stocker dâinfos sensibles en clair (mots de passe, donnĂ©es perso dĂ©taillĂ©esâŠ)
- Limiter Ă quelques kilo-octets
- Réserver ce stockage à des paramÚtres ou états simples
đ 2.4.3 Bases de donnĂ©es locales â Principe
Pour des données plus volumineuses ou structurées, on utilise une base de données locale.
Elle permet :
- recherches (requĂȘtes)
- tris
- relations entre données
- mises Ă jour complexes
2.4.3 Pourquoi une base locale ?
Utile pour :
- conserver une liste de données :
- notes, produits, messages, utilisateurs, etc.
- permettre Ă lâapp de fonctionner 100 % offline
- crĂ©er un cache local dâAPI :
- charger les données une fois,
- les relire mĂȘme sans rĂ©seau
2.4.3 Solutions principales
| Plateforme | Solution | Description |
|---|---|---|
| Android | Room (sur SQLite) | ORM moderne, facile depuis Kotlin |
| iOS | CoreData | Base orientée objets intégrée |
| Flutter |
sqflite, hive
|
SQLite ou base clĂ©âvaleur rapide |
| Ionic / Capacitor | @capacitor-community/sqlite |
Plugin SQLite natif |
2.4.3 Exemples dâusage â BDD locale
- App de recettes qui garde toutes les recettes consultées
- App de notes avec centaines dâentrĂ©es locales
- App de films qui garde les favoris hors ligne
2.4.3 SchĂ©ma logique â BDD locale
[ UI ] â [ ViewModel / Service ] â [ SQLite / CoreData ]
đŻ IdĂ©e : la vue ne parle jamais directement Ă la base.
Elle passe par une couche intermédiaire (service / ViewModel).
đ 2.4.4 Stockage de fichiers â Quand et pourquoi ?
Certaines apps doivent stocker des fichiers :
- photos
- documents scannés
- enregistrements audio
- fichiers téléchargés
Ici, ce ne sont plus des âlignes de BDDâ, mais des fichiers sur le stockage.
2.4.4 Types de fichiers courants
- Photos prises par lâutilisateur
- Documents scannés (factures, reçus)
- Fichiers PDF
- Notes vocales, enregistrements audio
- Fichiers téléchargés depuis Internet
2.4.4 APIs selon la plateforme
| Plateforme | API | Utilisation |
|---|---|---|
| Android |
File, MediaStore
|
Gestion fichiers et médias |
| iOS | FileManager |
Dossiers, lecture / écriture |
| Ionic / Capacitor | Filesystem |
API JS â systĂšme de fichiers natif |
| Flutter |
file_picker, path_provider
|
Choix de fichiers, stockage local |
Exemple : une app de scan stocke les documents localement avant upload.
2.4.4 Points dâattention â Fichiers
- GĂ©rer les permissions dâaccĂšs aux fichiers / mĂ©dias
- Faire attention Ă la taille (photos HD = gros fichiers)
- Nettoyer réguliÚrement les fichiers inutilisés
â Ă©viter de saturer le stockage
đ 2.4.5 Cache local et usage offline â Principe
Le cache local permet dâafficher du contenu mĂȘme si :
- le réseau est lent, ou
- complĂštement indisponible
Câest essentiel pour :
- éviter les écrans vides
- donner une impression de rapidité
2.4.5 Pourquoi utiliser un cache ?
- Réduire les appels réseau
- AccĂ©lĂ©rer lâaffichage (donnĂ©es dĂ©jĂ prĂ©sentes)
- Permettre un usage offline partiel
- Améliorer la perception de performance
Exemple : Twitter, Instagram ou YouTube affichent le dernier contenu chargé hors ligne.
2.4.5 Types de cache
-
Cache mémoire (RAM)
- trĂšs rapide
- disparaĂźt quand lâapp est fermĂ©e
-
Cache disque
- plus lent
- persiste entre les sessions
- idĂ©al pour donnĂ©es dâAPI, images, listes
2.4.5 Stratégies de lecture des données
| StratĂ©gie | Description | Cas dâusage |
|---|---|---|
| Cache-first | Lire le cache, puis mettre Ă jour en fond | App mĂ©tĂ©o, liste dâarticles |
| Network-first | RĂ©seau dâabord, cache en secours | Chat, donnĂ©es sensibles |
| Stale-while-revalidate | Afficher le cache puis rafraßchir en arriÚre-plan | Réseaux sociaux |
2.4.5 Bonnes pratiques â Cache
đ§âđ» Conseil dĂ©veloppeur :
Toujours enregistrer un timestamp avec les données du cache.
Comme en restauration :
- On Ă©tiquette chaque Ă©lĂ©ment du âfrigoâ (cache)
- On sait quand il a Ă©tĂ© mis, et si câest encore âfraisâ
đïž 2.4.6 Synchronisation online/offline â Principe
La synchronisation = garder la cohérence entre :
- les données locales
- les données serveur
⊠mĂȘme si lâutilisateur travaille offline.
2.4.6 Synchronisation â DĂ©fis principaux
- Conflits entre données locales et distantes
- Envoi des actions accumulées hors ligne
- Fiabilité en cas :
- de batterie vide
- de crash
- de fermeture brutale de lâapp
2.4.6 StratĂ©gie â File dâattente locale (queue)
Principe :
-
Chaque action utilisateur est enregistrée dans une queue :
- âAjouter une noteâ
- âModifier le profilâ
- âSupprimer un Ă©lĂ©mentâ
-
Ă la reconnexion :
- on rejoue la queue dans lâordre
- vers le serveur
2.4.6 StratĂ©gie â Marqueurs de version
Chaque enregistrement a un champ du type :
-
updatedAt - ou un numéro de version
En cas de conflit :
- la version la plus récente gagne
- ou selon une rÚgle métier décidée
2.4.6 StratĂ©gie â RĂ©solution des conflits
Stratégies possibles :
-
Last Writer Wins
â la derniĂšre modification lâemporte -
Serveur prioritaire
â le serveur est lâautoritĂ© finale -
Local prioritaire (offline-first)
â on fait confiance Ă ce que lâutilisateur a saisi
Exemple : app de notes â souvent la version locale la plus rĂ©cente prime.
â 2.4.7 Gestion des erreurs rĂ©seau â RĂ©alitĂ© du terrain
Le réseau mobile est :
- variable
- parfois lent
- parfois coupé
Une bonne app anticipe :
- les coupures
- les ralentissements
- les erreurs HTTP
2.4.7 Détection du statut réseau
Outils fréquents :
- Android :
ConnectivityManager - iOS :
NWPathMonitor - Ionic / Capacitor : plugin
Network - Flutter : package
connectivity_plus
Permet dâafficher des messages :
- âVous ĂȘtes hors ligneâ
- âConnexion lente, veuillez patienterâ
- âConnexion instable â affichage du cacheâ
2.4.7 Stratégies de résilience
- Retry exponentiel : 1s â 2s â 4s â 8sâŠ
- Fallback local : cache, BDD locale
- Désactivation de certaines actions hors ligne
- Sauvegarde des actions dans une queue locale
Exemple :
Une app de livraison peut empĂȘcher lâenvoi dâune commande hors ligne,
mais continuer dâafficher les menus via le cache.
đ§© 2.4.8 ActivitĂ© pratique â OĂč stocker quoi ?
(clĂ©âvaleur / base de donnĂ©es / fichiers / pas de persistance)
đ Objectif
Comprendre oĂč et comment stocker chaque type de donnĂ©e dans une app mobile.
2.4.8 đ Contexte â App CityQuest
Vous travaillez sur CityQuest, une app de chasse au trésor en ville.
Fonctionnalités :
- QuĂȘtes gĂ©olocalisĂ©es (Ă©nigmes, points dâintĂ©rĂȘt, QR codes Ă scanner)
- Chaque quĂȘte rapporte des points
- Une quĂȘte peut ĂȘtre validĂ©e avec une photo
- Lâutilisateur peut voir :
- ses quĂȘtes en cours
- ses quĂȘtes terminĂ©es
- Lâapp doit fonctionner raisonnablement mĂȘme avec un rĂ©seau faible (cache local)
2.4.8 Ce quâon modĂ©lise / ne modĂ©lise pas
On se concentre sur les données stockées sur le téléphone :
- pas de schéma complet de BDD serveur
- pas de détails sur le profil utilisateur cÎté back
đŻ Objectif : apprendre Ă choisir le bon type de stockage local.
2.4.8 Consignes de lâexercice
Pour chaque donnée ci-dessous, indiquez dans quel type de stockage vous la placeriez :
- ClĂ©âvaleur
- Base de données locale
- Fichiers
- Pas besoin de persistance (si justifié)
âïž Justifiez chaque choix en 1 phrase.
2.4.8 Données à analyser (1/2)
- Token dâauthentification (JWT, OAuth)
- ParamĂštre du thĂšme (sombre / clair)
- Choix de lâutilisateur pour tĂ©lĂ©charger les images :
- uniquement en Wi-Fi
- ou Wi-Fi + 5G
- DerniĂšre position GPS connue (pour centrer la carte au prochain lancement)
- Liste des quĂȘtes disponibles dans la ville
- titre, description, coordonnées GPS, difficulté, points
2.4.8 Données à analyser (2/2)
-
Ătat dâune quĂȘte pour lâutilisateur
(non commencée,en cours,terminée) -
Historique des quĂȘtes terminĂ©es
(dizaines ou centaines dâentrĂ©es) -
Cache des quĂȘtes Ă proximitĂ© rĂ©cupĂ©rĂ©es depuis lâAPI
(afficher mĂȘme si le rĂ©seau est lent) -
Photo de validation dâune quĂȘte prise par lâutilisateur
-
Fichiers de logs dâerreur pour envoi ultĂ©rieur au support
(stack traces, messages techniques)
2.4.8 Format de réponse suggéré
| Donnée | Type de stockage choisi | Justification (1 phrase) |
|---|---|---|
| Token dâauthentification | ⊠| ⊠|
| ParamÚtre du thÚme | ⊠| ⊠|
| ⊠| ⊠| ⊠|
đŹ Lâobjectif est moins dâavoir âla bonne rĂ©ponseâ que de savoir argumenter.
đ 2.4.9 RĂ©fĂ©rences
-
Android Room
https://developer.android.com/training/data-storage/room -
iOS CoreData
https://developer.apple.com/documentation/coredata -
Capacitor â Storage & SQLite
https://capacitorjs.com/docs -
Flutter â sqflite
https://pub.dev/packages/sqflite -
W3C â IndexedDB API
https://developer.mozilla.org/docs/Web/API/IndexedDB_API
đŸ 2.4 Persistance et scĂ©narios offline
By tirtho
đŸ 2.4 Persistance et scĂ©narios offline
- 80