Une application mobile qui marche sans réseau : ce que ça change
Oussama
Développeur mobile

En bref
Comment concevoir une application mobile qui fonctionne hors ligne ?
En considérant l'appareil comme la source de vérité temporaire et le serveur comme un point de synchronisation, pas l'inverse. Concrètement : une base locale sur le téléphone, une file d'opérations en attente rejouées à la reconnexion, un identifiant généré côté appareil pour ne pas dépendre du serveur, et une règle de résolution de conflits décidée avec le métier. Le hors ligne n'est pas une option qu'on ajoute — c'est une décision d'architecture qui doit être prise au début du projet.
Un technicien en sous-sol. Un livreur dans un parking. Un commercial dans un TGV entre deux tunnels. Trois situations où l’application doit continuer à fonctionner, et où « il faut du réseau » n’est pas une réponse acceptable.
Le hors ligne est le sujet mobile qui coûte le plus cher quand il arrive tard, et qui coûte raisonnablement quand il est décidé au début. Voici pourquoi, et comment nous le construisons.
Le renversement à comprendre
Une application connectée classique fonctionne ainsi : l’utilisateur agit, l’application appelle le serveur, attend la réponse, affiche le résultat. Le serveur est la source de vérité, l’écran en est le reflet.
Une application hors ligne inverse cette logique. L’utilisateur agit, l’application enregistre localement, affiche immédiatement, et synchronise plus tard. L’appareil devient une source de vérité temporaire ; le serveur devient un point de rendez-vous.
Ce renversement touche tout : le stockage, la navigation, la gestion des erreurs, les identifiants, l’affichage. C’est pour cela qu’on ne l’ajoute pas à la fin — il faudrait réécrire la couche de données et une bonne partie des écrans.
Les quatre briques
Une base de données locale. Pas un simple cache : une vraie base sur l’appareil, qui contient tout ce dont l’utilisateur a besoin pour travailler. L’écran lit toujours cette base locale, jamais le réseau directement. C’est ce qui rend l’application instantanée, y compris avec du réseau — un effet de bord très apprécié.
Une file d’opérations en attente. Chaque action de l’utilisateur — créer, modifier, supprimer — est enregistrée localement puis déposée dans une file. Quand le réseau revient, la file se rejoue dans l’ordre. Une opération qui échoue est retentée ; une opération refusée définitivement doit être remontée à l’utilisateur, pas effacée en silence.
Des identifiants générés sur l’appareil. C’est le détail qui change tout. Si un nouvel enregistrement attend son identifiant du serveur, rien de ce qui en dépend ne peut être créé hors ligne. En générant un identifiant unique côté appareil, on peut créer un dossier, y rattacher trois photos et un commentaire, le tout sans réseau, et synchroniser l’ensemble d’un bloc.
Une règle de résolution des conflits. Deux personnes modifient le même enregistrement, l’une hors ligne. À la synchronisation, il faut trancher. Cette règle est une décision métier, pas technique.
Les conflits : la vraie question
C’est le sujet qu’on repousse et qui finit par décider de la crédibilité de l’application.
Le dernier qui écrit gagne. Simple, et suffisant quand chaque enregistrement n’a qu’un seul utilisateur légitime — le compte-rendu d’intervention d’un technicien, par exemple. Dangereux dès que plusieurs personnes touchent aux mêmes données : on perd des modifications sans le savoir.
La fusion champ par champ. Si deux personnes ont modifié des champs différents du même enregistrement, on garde les deux. Cela couvre l’immense majorité des cas réels et ne demande qu’un suivi des champs modifiés. C’est la stratégie que je recommande par défaut.
L’arbitrage humain. L’application détecte le conflit, met l’enregistrement de côté et demande à quelqu’un de trancher. Coûteux à construire, mais indispensable quand l’enjeu est fort — une donnée financière ou réglementaire.
Le vrai travail consiste à poser la question au métier, dossier par dossier : « si deux personnes modifient ça en même temps, que doit-il se passer ? » La réponse est rarement la même partout, et elle n’est presque jamais « on ne sait pas, faites au mieux ».
Ce qu’il faut montrer à l’utilisateur
Une application hors ligne ment un peu : elle affiche comme acquis ce qui n’est pas encore enregistré côté serveur. Il faut donc être transparent, sans être anxiogène.
Trois éléments suffisent, et ils ne sont pas négociables :
L’état de la synchronisation, discret mais visible en permanence. « À jour », « 3 éléments en attente », « hors ligne ». L’utilisateur doit pouvoir répondre à la question « est-ce que mon travail est parti ? » sans chercher.
Un marquage des éléments non synchronisés. Une pastille, une teinte différente. Cela évite qu’un utilisateur affirme en réunion qu’une donnée est transmise alors qu’elle dort sur son téléphone.
Un message clair en cas d’échec définitif. Une opération refusée par le serveur ne doit jamais disparaître silencieusement. C’est la faute la plus grave qu’une application hors ligne puisse commettre, parce qu’elle détruit la confiance de façon irrattrapable.
Photo : Quentin Hupin — licence CC0.
Photo : Burst — licence CC0.
Ce qu’on synchronise, et quand
Tout ne descend pas sur l’appareil. Un catalogue de deux millions de références n’a rien à faire dans le téléphone d’un livreur.
La règle : descendre le périmètre de travail de l’utilisateur, pas la base. Ses tournées du jour et du lendemain, ses clients, les références qu’il utilise réellement. Cela suppose une notion de périmètre côté serveur, définie avec le métier.
Pour la synchronisation elle-même, on ne renvoie jamais tout. On ne récupère que ce qui a changé depuis le dernier échange, en s’appuyant sur un marqueur de version. Une synchronisation complète doit rester une opération exceptionnelle, déclenchable manuellement en cas de doute.
Quant au moment : à l’ouverture de l’application, au retour du réseau, et périodiquement en arrière-plan lorsque le système l’autorise. Sur ce dernier point, les deux plateformes limitent fortement ce qu’une application peut faire quand elle n’est pas au premier plan. Il ne faut donc jamais promettre une synchronisation en arrière-plan à heure fixe : le système décide, pas nous.
Le piège du « presque connecté »
Le pire cas n’est pas l’absence de réseau. C’est le réseau très mauvais.
Hors ligne, tout est clair : l’application bascule en mode local. Avec une barre de signal et trois kilo-octets par seconde, le système considère qu’il y a du réseau, les requêtes partent, et attendent. L’application se fige, l’utilisateur relance, deux requêtes identiques partent.
Trois précautions, systématiquement :
Des délais d’attente courts. Mieux vaut basculer en mode local au bout de quelques secondes que faire patienter indéfiniment.
Des opérations idempotentes. Envoyer deux fois la même création ne doit produire qu’un seul enregistrement. L’identifiant généré côté appareil rend cela naturel : le serveur reconnaît qu’il a déjà traité cette opération.
Des tentatives espacées progressivement. Un réseau saturé ne se répare pas en le sollicitant plus fort. Chaque échec double l’attente avant la tentative suivante.
Ce que ça coûte
Concevoir une application hors ligne dès le départ représente en gros un tiers d’effort supplémentaire sur la couche de données par rapport à une application connectée. Ce n’est pas négligeable, et cela reste maîtrisé.
L’ajouter après coup revient à réécrire la couche de données, à reprendre les écrans qui affichent des états de chargement, et à revoir toute la gestion d’erreur. En pratique, c’est plus proche d’une reconstruction que d’une évolution.
D’où la seule question qui compte au démarrage du projet : est-ce qu’un utilisateur se trouvera un jour sans réseau au moment de s’en servir ? Si la réponse est oui, même occasionnellement, la décision se prend maintenant. Si elle est non — une application utilisée uniquement au bureau — alors il ne faut surtout pas payer cette complexité.
Il n’y a pas de position intermédiaire confortable, et c’est ce qui rend cette question si importante à poser le premier jour.