Aller au contenu
Demander un avis
Tutoriels

CI/CD mobile avec Fastlane : livrer sur TestFlight et Google Play en une seule commande

21 min de lecture
CI/CD mobile avec Fastlane : livrer sur TestFlight et Google Play en une seule commande

Livrer une application mobile à la main, c’est une heure de manipulations à chaque version : ouvrir Xcode, choisir le bon profil de provisionnement, incrémenter le numéro de build, archiver, attendre, téléverser, recommencer côté Android avec un autre outil et un autre mot de passe. Et le jour où c’est un collègue qui s’en charge, la signature échoue pour une raison que personne n’arrive à reproduire.

Fastlane existe justement pour transformer cette corvée en une commande. C’est un ensemble d’actions Ruby que l’on décrit dans un fichier, le Fastfile, et que l’on déclenche ensuite depuis son terminal ou depuis un serveur d’intégration continue. Ce tutoriel s’adresse aux développeurs mobiles qui veulent arrêter de livrer au clic, et aux porteurs de projet qui veulent comprendre ce qu’ils paient quand une agence facture « la mise en place du pipeline de livraison ».

Ce qu’on obtient au bout : une lane iOS qui produit un fichier .ipa signé et l’envoie sur TestFlight, une lane Android qui produit un .aab signé et le pousse sur le canal Google Play de votre choix, et une lane maîtresse qui enchaîne les deux en prévenant l’équipe si quelque chose casse. Les captures qui suivent reprennent chaque étape dans l’ordre.

Les points essentiels à retenir

  • match range les certificats et les profils de provisionnement chiffrés dans un dépôt Git privé, pour que tous les postes de l’équipe et toutes les machines d’intégration continue signent avec exactement les mêmes identités.
  • Côté iOS, l’ordre à l’intérieur de la lane n’est pas négociable : match, puis increment_build_number, puis gym. Le chemin du .ipa produit doit être capturé, car pilot en a besoin juste après.
  • Pour l’authentification non interactive, on préfère une clé API App Store Connect (identifiant de clé, identifiant d’émetteur, chemin du fichier) aux variables FASTLANE_USER et FASTLANE_PASSWORD.
  • Côté Android, le keystore reste hors du dépôt de code et ses mots de passe passent par des variables d’environnement. supply a besoin d’un compte de service Google disposant de la permission « Edit releases ».
  • Une lane maîtresse appelle les sous-lanes de chaque plateforme, valide les secrets au démarrage et embarque un bloc error qui notifie Slack ou Teams avec les journaux d’erreur.

Étape 1 : installer Fastlane et confier la signature à match

L’installation passe par RubyGems ou par Homebrew, selon ce que votre machine a déjà. Une fois l’outil disponible, on se place à la racine du projet et on lance fastlane init. Cette commande crée les deux fichiers de configuration de départ : le Fastfile, qui contiendra les lanes, et l’Appfile, qui garde l’identifiant de l’application et le compte associé.

Vient ensuite la partie qui règle 80 % des douleurs iOS : la synchronisation des certificats et des profils de provisionnement avec l’outil match. On décrit un Matchfile qui contient deux informations, l’identifiant de l’application et l’URL du dépôt Git privé où les éléments de signature seront rangés.

Schéma d'installation de Fastlane et extrait de Matchfile avec git_url et app_identifier
Les quatre gestes de la mise en place : installer Fastlane, lancer fastlane init, écrire le Matchfile, puis exécuter match pour chiffrer et pousser les éléments de signature.

On exécute alors les deux commandes dans l’ordre :

  1. fastlane match development, pour les identités de développement ;
  2. fastlane match appstore, pour celles de distribution.

Ces commandes génèrent les certificats et les profils nécessaires, les chiffrent avec un secret partagé, puis les poussent vers le dépôt Git désigné. Ce dépôt doit être privé : il contient de quoi signer votre application. Un dépôt public au moment de la mise en place, c’est un incident de sécurité, pas une étourderie.

Pourquoi tout ce cérémonial ? Parce que match garantit que chaque membre de l’équipe et chaque machine d’intégration continue utilisent des identités de signature identiques et valides. Cette standardisation supprime la famille d’erreurs de signature qui empoisonne le développement iOS, celle où le build passe sur un poste et échoue sur un autre sans qu’on comprenne pourquoi.

Documentation officielle de Fastlane ouverte dans un navigateur, avec le sommaire des guides iOS, Android et multiplateformes
La documentation de l’outil range ses guides par plateforme (iOS, Android) et par technologie multiplateforme (React Native, Flutter, NativeScript). La page d’accueil montre déjà une lane beta type : increment_build_number, build_app, upload_to_testflight.

Si vous en êtes encore à cadrer votre projet, sachez que cette étape se pose noir sur blanc : qui détient le dépôt de signature, qui a accès au secret partagé, et ce que devient l’ensemble en fin de contrat. Ce sont des lignes à mettre dans le cahier des charges de votre application, pas des questions à découvrir la veille d’une mise en production.

Étape 2 : la lane iOS, gym pour l’archive puis pilot pour TestFlight

On définit maintenant une lane dédiée à la construction iOS. L’action qui compile l’application et empaquette l’archive s’appelle gym. Trois paramètres sont obligatoires : le nom du scheme, la configuration (typiquement Release) et la méthode d’export, qui vaut app-store pour une soumission ou ad-hoc pour un test interne.

Lane Fastlane build_ios_release enchaînant match, increment_build_number et gym avec ses paramètres
La lane iOS au complet : match récupère les éléments de signature, increment_build_number met à jour le numéro de build, gym compile et range le résultat dans un dossier de sortie connu.

Deux précautions font toute la différence entre une lane qui marche et une lane qui échoue une fois sur trois.

La première : intégrer increment_build_number immédiatement avant l’exécution de gym. Cette action met à jour le numéro de build dans le fichier de projet et garantit un identifiant unique pour chaque soumission à App Store Connect. Sans elle, la plateforme refuse un build dont le numéro a déjà servi, et vous perdez le bénéfice de l’automatisation dès la deuxième livraison de la journée.

La seconde : s’assurer que l’action match tourne juste avant gym. C’est ce passage qui télécharge sur la machine de build le bon profil de provisionnement chiffré et le bon certificat. Sur un serveur d’intégration continue qui repart d’une machine vierge à chaque exécution, c’est la seule façon d’obtenir une signature qui aboutit.

Enfin, le chemin de sortie du fichier .ipa généré doit être capturé explicitement. Cet artefact est l’entrée de l’étape suivante : sans lui, l’action de dépôt n’a rien à envoyer.

Envoyer la version sur TestFlight avec pilot

L’action pilot téléverse le .ipa compilé directement vers App Store Connect pour distribution sur TestFlight. Le chemin de l’artefact produit par gym lui est passé en paramètre principal.

Tableau des paramètres de l'action pilot : ipa, distribute_external et changelog
Trois paramètres suffisent pour un envoi TestFlight : le chemin de l’artefact, l’ouverture aux testeurs externes, et les notes de version. Pilot gère ensuite le téléversement et le traitement TestFlight tout seul.

Deux réglages méritent une explication.

  • distribute_external : à passer à true si le build est destiné à des testeurs externes, ce qui déclenche une revue d’Apple. Pour un cercle interne, on s’en passe et la diffusion est immédiate.
  • changelog : les notes de version destinées aux testeurs. On peut les écrire en dur, ou mieux, structurer le contenu en le lisant depuis un fichier Markdown dédié, ce qui évite de modifier le Fastfile à chaque livraison.

Reste la question de l’authentification. Pour un usage non interactif et sécurisé, on évite de stocker un mot de passe. La bonne méthode consiste à configurer une clé API App Store Connect depuis le portail développeur Apple, puis à déclarer trois valeurs en variables d’environnement : l’identifiant de la clé, l’identifiant de l’émetteur et le chemin du fichier de clé. Cette approche est nettement préférable aux variables FASTLANE_USER et FASTLANE_PASSWORD, et c’est la seule qui tienne dans un environnement d’intégration continue partagé. Si la publication elle-même vous est encore floue, notre tutoriel sur la publication d’une application sur l’App Store détaille ce qui se passe côté console.

Étape 3 : la lane Android, du keystore au fichier .aab

Côté Android, la signature ne passe pas par un service central mais par un fichier que vous générez et que vous gardez. On commence donc par produire le keystore avec l’utilitaire keytool, en précisant l’alias de la clé et la durée de validité souhaitée.

Ce fichier se range en dehors du dépôt de code source. Ses identifiants (mot de passe du magasin, mot de passe de la clé, alias) se configurent en variables d’environnement dans l’environnement de build.

Étapes de configuration Android : génération du keystore, variables d'environnement, fastlane supply init et compte de service Google Play
Les quatre variables d’environnement attendues côté Android, et la condition à ne pas rater : le compte de service doit avoir la permission « Edit releases » dans les réglages d’accès API de la Play Console.

On initialise ensuite la configuration de déploiement Google Play avec fastlane supply init. L’authentification auprès de Google Play réclame un fichier de clé JSON de compte de service. Ce fichier se génère dans la console Google Cloud, et il faut lui accorder la permission « Edit releases » dans les réglages d’accès API de la Google Play Console. Le chemin absolu vers ce JSON est fourni à Fastlane via le paramètre json_key_file ou une variable d’environnement équivalente.

Produire l’AAB avec l’action gradle

Pour générer l’artefact, on s’appuie sur l’action gradle de Fastlane, qui exécute les tâches Gradle du projet. La tâche visée est bundleRelease sur le module applicatif, celle qui produit l’Android App Bundle.

Lane build_android_aab appelant l'action gradle avec la tâche bundleRelease et le paramètre project_dir
La lane Android tient en quatre lignes. Le paramètre project_dir sert quand le Fastfile ne se trouve pas dans le dossier qui contient le wrapper Gradle, ce qui est le cas courant sur un projet multiplateforme.

Trois points de vigilance ici :

  1. Le fichier build.gradle du projet doit référencer correctement les variables d’environnement du keystore pour signer l’artefact de release. Une lane qui s’exécute sans erreur peut très bien produire un bundle non signé.
  2. Si le Fastfile n’est pas dans le répertoire racine qui contient le wrapper Gradle, il faut préciser le paramètre project_dir.
  3. L’action gradle renvoie le chemin du fichier .aab signé. Ce format est obligatoire pour toute soumission Google Play moderne, l’APK ne suffit plus.

Avant d’aller plus loin, confirmez toujours que le processus de build a bien appliqué la configuration de signature de release. C’est une vérification de dix secondes qui évite un rejet à l’autre bout de la chaîne.

Combien coûterait votre application ?

Un devis estimatif détaillé en six questions, à partir des fourchettes de notre guide des prix.

Étape 4 : choisir son canal Google Play et déployer par paliers

L’action supply téléverse le .aab généré directement vers la Google Play Console. Le chemin du fichier lui est passé par le paramètre dédié aab, et le canal de destination par le paramètre de track.

Tableau des canaux Google Play : internal, alpha, beta et production, avec les paramètres aab, release_notes et rollout
Les canaux Google Play et leur usage : internal pour l’équipe, alpha et beta pour des groupes de test plus larges, production pour le public. Le paramètre rollout gère la montée progressive.

Le choix du canal structure toute votre stratégie de sortie :

  • internal : accès immédiat pour les testeurs de l’équipe interne.
  • alpha et beta : des groupes de test plus larges, en test fermé ou ouvert.
  • production : le canal de diffusion publique.

Deux paramètres complètent le tableau. Les notes de version localisées se définissent avec release_notes, structuré par code de langue (par exemple en-US). Et pour les sorties en production, on implémente un déploiement progressif en réglant rollout sur une valeur en pourcentage : 0.05 diffuse la version à 5 % des utilisateurs. Vous gardez la main si un plantage apparaît, ce qui est plus confortable qu’une correction en urgence sur 100 % du parc.

Page de documentation de l'action supply de Fastlane affichée dans un navigateur, avec sa liste de fonctionnalités
L’action supply est l’alias de upload_to_play_store. Elle couvre le téléversement des binaires et des bundles, mais aussi la mise à jour des métadonnées, des icônes et des captures pour plusieurs langues.

Ce que fait supply tient en une phrase : elle crée la nouvelle version, téléverse l’artefact et affecte le build au canal demandé. La dernière étape manuelle du cycle Android disparaît.

Étape 5 : synchroniser les textes et les captures de la fiche store

Un pipeline de livraison qui s’arrête au binaire ne va qu’à moitié au bout. Les descriptions, les mots-clés et les titres se gèrent eux aussi en fichiers, rangés dans un répertoire de métadonnées organisé strictement par code de langue.

Arborescence des métadonnées Fastlane par langue, avec deliver pour iOS et supply pour Android
La structure attendue : fastlane/metadata/[langue]/[type].txt. C’est deliver qui synchronise côté iOS, supply côté Android, et frameit ou screengrab qui préparent les captures.

La synchronisation se fait avec l’action deliver pour iOS et l’action supply pour Android. Les captures d’écran suivent la même logique : on place les images dans les sous-répertoires spécifiques à chaque plateforme, à l’intérieur de la structure de métadonnées, et le téléversement devient automatique.

Pour la présentation, Fastlane fournit frameit côté iOS et screengrab côté Android. Ces outils capturent et encadrent les captures pour les différentes tailles d’appareils, de manière à ce que les images respectent les exigences des stores avant que la synchronisation ne se lance. C’est là que le travail de référencement sur les stores cesse d’être un fichier partagé que personne ne met à jour, et devient une partie versionnée de votre dépôt.

Étape 6 : une lane maîtresse et un bloc error qui prévient l’équipe

Dernière pièce : structurer le Fastfile en sous-lanes claires et spécifiques à chaque plateforme, du type build_and_deploy_ios et build_and_deploy_android. On crée ensuite une lane maîtresse unique, par exemple release_production, qui appelle ces sous-lanes de manière séquentielle.

Lane release_production appelant les sous-lanes iOS et Android, suivie d'un bloc error qui notifie Slack
Un seul point d’entrée pour tout le cycle de sortie, et un bloc error qui s’exécute à la moindre défaillance pour envoyer le détail de l’exception dans un canal d’équipe.

Trois habitudes rendent cette lane maîtresse fiable au quotidien.

  1. Valider les secrets d’abord. Toutes les variables d’environnement et les identifiants nécessaires sont vérifiés explicitement au début de l’exécution, avant la moindre compilation. Une lane qui s’arrête en trois secondes parce qu’une clé manque coûte moins cher qu’une lane qui échoue vingt minutes plus tard, au moment du téléversement.
  2. Gérer l’échec. Le bloc error défini dans le Fastfile s’exécute à la moindre défaillance. Il permet de traiter les échecs proprement, par exemple en notifiant automatiquement un canal de communication comme Slack ou Microsoft Teams, avec les journaux d’erreur détaillés.
  3. Garder une seule commande. Cette structure unifiée donne un point d’entrée unique et fiable pour les systèmes d’intégration et de déploiement continus, qui pilotent alors tout le cycle de sortie multiplateforme.

Le gain se mesure sur la durée : ce n’est pas la première livraison qui rentabilise le pipeline, ce sont la vingtième et la centième. Cet investissement de départ fait partie des postes que l’on chiffre dans le guide des prix d’une application mobile, et il continue de produire des effets bien après la sortie, comme on le détaille dans notre article sur le coût de maintenance d’une application mobile.

Ce que montrent les écrans, fonction par fonction

Tout ce qui précède finit à un seul endroit : la fiche que voit un utilisateur avant de télécharger. Voici quatre écrans publics de fiches App Store françaises, lus sous l’angle de la livraison automatisée. Chaque visuel est un fichier qui vit dans votre dépôt et que deliver ou supply pousse à votre place.

Premier visuel de la fiche App Store de Deliveroo : nom de la marque, accroche et photos de plats
Deliveroo, premier visuel de fiche : le nom de la marque, l’accroche « Restos et courses livrés chez vous. » et trois photos de plats sur fond turquoise.

Ce qu’on voit : pas d’interface, une affiche. Un mot-symbole, une promesse en deux lignes, des photographies de burger, de poke bowl et de sushis. Le geste : aucun, à ce stade. C’est la vignette que l’on balaie dans les résultats de recherche du store, avant même d’avoir ouvert quoi que ce soit. Le lien avec l’écran suivant : c’est le déclencheur externe au sens de Hooked (2014), celui qui décide du tap sur « Obtenir ». Du point de vue de la livraison, ce fichier est rangé par code de langue dans le dossier de métadonnées, ce qui explique pourquoi la version française porte une accroche française et non une traduction approximative poussée à la main. Le parcours complet est décortiqué dans notre modèle d’application Deliveroo.

Écran de recherche Deliveroo présenté dans un cadre iPhone : champ Rechercher, onglets et catégories
Deliveroo, écran de recherche : un champ « Rechercher », trois onglets (Tout, Restaurants, Commerces) et une section « Parcourir par catégorie » avec des vignettes photo.

Ce qu’on voit : une vraie interface cette fois, présentée dans un cadre d’appareil, avec un champ de saisie actif, une segmentation par type de commerce et des catégories illustrées. Le geste : taper dans le champ, ou faire défiler les catégories du pouce quand on ne sait pas encore ce qu’on veut. Le lien avec l’écran suivant : c’est l’action, immédiatement suivie de la récompense variable, puisqu’on ignore ce que la recherche va faire remonter. Pour un pipeline, cette capture est le cas d’école : l’heure affichée dans la barre d’état et la taille de l’écran doivent être cohérentes sur toutes les déclinaisons d’appareils. C’est exactement le travail que frameit et screengrab font en une commande.

Visuel de fiche Uber Eats sur fond vert avec le slogan Obtenez tout ce que vous voulez et une mention légale
Uber Eats, visuel de fiche : un aplat vert, le slogan « Obtenez tout ce que vous voulez », une photo de plat et une mention en petits caractères sur la disponibilité selon les marchés.

Ce qu’on voit : une composition typographique plein cadre, et surtout une mention légale en bas, qui nuance la promesse et précise que la disponibilité des articles varie selon les marchés. Le geste : la lecture, rien de plus. Le lien avec l’écran suivant : déclencheur là aussi, mais avec une contrainte supplémentaire, et c’est le détail qui intéresse un pipeline de livraison. Cette mention doit exister dans chaque langue, avec la formulation juridique attendue par chaque marché. Un dossier de métadonnées par code de langue est la seule façon de ne pas se retrouver un jour avec une mention anglaise sur une fiche française.

Page d'accueil Uber Eats dans un cadre iPhone : offres spéciales, cartes de restaurants et barre d'onglets
Uber Eats, page d’accueil : adresse et créneau en haut, section « Offres spéciales », cartes de restaurants avec frais et délai de livraison, et une barre à cinq onglets en bas.

Ce qu’on voit : l’écran le plus dense des quatre. Une adresse de livraison modifiable, un bandeau promotionnel chiffré, des cartes de restaurants portant chacune leur délai annoncé, un bloc dédié aux courses de la semaine, et une navigation à cinq onglets. Le geste : faire défiler, taper une carte, revenir par les onglets. Le lien avec l’écran suivant : action et récompense variable s’enchaînent à chaque défilement, puis l’adresse enregistrée devient un investissement qui alimentera tous les déclencheurs suivants. Un détail trahit ici la fabrication de la capture : les montants sont en dollars et l’adresse est américaine, sur une fiche destinée au marché français. C’est précisément le genre d’écart qu’une génération automatisée des captures, langue par langue, supprime. Le fonctionnement de ce type de service est détaillé dans notre modèle d’application Uber Eats.

Les erreurs fréquentes

  • Continuer à gérer les profils de provisionnement à la main. C’est le point de départ de tout le reste. Tant que chaque poste bricole ses propres identités, aucune automatisation ne tient.
  • Mettre le dépôt de signature en public. Le dépôt Git qui reçoit les certificats chiffrés par match doit être privé. Ce n’est pas une recommandation de confort.
  • Oublier increment_build_number. App Store Connect refuse un numéro de build déjà utilisé. Sans incrément automatique, la deuxième livraison de la journée échoue.
  • Lancer gym sans match juste avant. Sur une machine de build vierge, le profil et le certificat ne sont pas là. La signature échoue, et le message d’erreur ne vous dira pas franchement pourquoi.
  • Stocker un identifiant Apple et son mot de passe dans la configuration d’intégration continue. La clé API App Store Connect existe pour ça et se révoque proprement.
  • Committer le keystore Android dans le dépôt. Le fichier reste à l’extérieur, ses mots de passe passent par des variables d’environnement.
  • Oublier la permission « Edit releases » sur le compte de service. La clé JSON est valide, l’authentification passe, et le dépôt échoue quand même.
  • Passer directement en production à 100 %. Le paramètre rollout existe pour livrer par paliers et garder une porte de sortie.
  • Ne pas définir de bloc error. Un pipeline qui échoue en silence est plus dangereux qu’une livraison manuelle, parce que personne ne surveille plus rien.

Questions fréquentes

À quoi sert exactement match, et pourquoi le dépôt doit-il être privé ?

Match génère les certificats et les profils de provisionnement, les chiffre avec un secret partagé et les pousse dans un dépôt Git. Tout poste ou toute machine d’intégration continue qui connaît le secret peut alors récupérer des identités de signature identiques et valides. Le dépôt doit être privé parce qu’il contient, même chiffré, l’ensemble du matériel de signature de votre application.

Peut-on vraiment livrer iOS et Android d’une seule commande ?

Oui, c’est l’objectif de la lane maîtresse. On définit une sous-lane par plateforme, puis une lane unique qui les appelle séquentiellement. Cette lane vérifie d’abord que tous les secrets nécessaires sont présents, puis enchaîne construction et dépôt sur les deux stores. Le système d’intégration continue n’a plus qu’un seul point d’entrée à connaître.

Fastlane fonctionne-t-il sur un projet Flutter ou React Native ?

La documentation officielle range ses guides de démarrage en trois familles : iOS, Android, et multiplateforme, cette dernière catégorie listant explicitement React Native, Flutter et NativeScript. Le raisonnement reste le même dans tous les cas, puisque ce sont les mêmes stores et les mêmes exigences de signature en bout de chaîne. Si le choix de la technologie n’est pas encore arrêté, notre comparatif Flutter ou React Native aborde la question en amont.

Comment fonctionne un déploiement progressif sur Google Play ?

Sur le canal de production, le paramètre rollout de l’action supply prend une valeur en pourcentage. Une valeur de 0.05 correspond à un déploiement initial sur 5 % des utilisateurs. Vous observez le comportement réel de cette fraction avant d’élargir. Pour faire chiffrer la mise en place complète d’un tel pipeline sur votre projet, demandez un devis.

Quiz : avez-vous tout retenu ?

Quelle commande génère le Fastfile et l’Appfile à la racine du projet ?
  • fastlane setup
  • fastlane init
  • fastlane new
  • fastlane gym

fastlane init, lancée depuis la racine du projet, crée les deux fichiers de configuration de départ : le Fastfile qui contiendra les lanes, et l’Appfile qui garde l’identifiant de l’application.

Où match range-t-il les certificats et les profils de provisionnement ?
  • Dans le dossier fastlane du projet
  • Dans un dépôt Git privé, chiffrés avec un secret partagé
  • Dans les variables d’environnement du serveur d’intégration continue
  • Directement sur App Store Connect

Dans un dépôt Git privé désigné par le Matchfile. Les éléments sont chiffrés avec un secret partagé avant d’être poussés, ce qui permet à toute l’équipe et aux machines de build d’utiliser les mêmes identités.

Quel format d’artefact les soumissions Google Play modernes exigent-elles ?
  • Le fichier .apk
  • Le fichier .aab signé
  • Le fichier .ipa
  • Une archive .zip du projet

L’Android App Bundle, produit par la tâche Gradle bundleRelease. L’action gradle de Fastlane renvoie le chemin du fichier signé, que supply reprend ensuite via son paramètre aab.

Que provoque le réglage rollout: 0.05 dans l’action supply ?
  • Une attente de 5 jours avant publication
  • Une diffusion initiale auprès de 5 % des utilisateurs
  • La publication sur 5 canaux à la fois
  • La traduction de la fiche en 5 langues

Il s’agit d’un déploiement progressif : la nouvelle version n’est proposée qu’à 5 % du parc dans un premier temps, ce qui laisse le temps d’observer avant d’élargir à tout le monde.

Besoin d’un avis technique sur votre projet d’application ?

Digital Unicorn, agence d’applications mobiles présentée dans ce guide, propose un échange gratuit de trente minutes pour situer votre projet : périmètre, technologies, ordre de grandeur budgétaire.

Réserver un créneau avec Digital Unicorn

Ou directement : contact@digitalunicorn.fr · 06 32 64 24 80. L’agence répond en général dans les 30 minutes (jours ouvrés).

Cadre du projet, ensuite

Un tutoriel store ou technique ne remplace pas un cahier des charges. Quand le périmètre existe (deux stores, un back-office, un paiement), ouvrez le modèle de CDC, les fourchettes du guide des prix, et la grille de devis. Les captures annotées de nos articles suivent la même logique que l’analyse d’écrans du CDC : une source réelle, une exigence écrite, pas une moodboard.

Fourchettes HT, France : MVP 15 000 à 40 000 €, ambition moyenne 40 000 à 120 000 €, complexe 120 000 à 300 000 €. Maintenance 15 à 20 % par an.

Par la rédaction d’Agence Application Mobile. Article publié le 9 septembre 2026.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Avis technique gratuit

Parlez de votre projet à un expert

Décrivez votre application en quinze minutes : vous repartez avec un avis technique sous 48 h. Périmètre, technologies pertinentes et ordre de grandeur budgétaire. Sans engagement.

Sans engagement. Pas de démarchage, pas de liste de diffusion.