EL TIGRE, expert Flutter, vous propose dans cet article, une architecture simple et robuste pour gérer vos différentes phases de développement d’un projet Flutter. Toute l’application reposera dessus, elle est donc primordiale !
Ce tutoriel n’a pas pour but de vous apprendre Flutter ni même Dart, c’est un support sur lequel vous pourrez vous appuyer afin de commencer proprement un projet. Il est réalisé avec VSCode, mais vous pouvez utiliser votre éditeur préféré !
Au préalable
- Avoir installé Flutter
- Avoir des notions de base de Dart et Flutter
La base de l’application
Commencez par créer un nouveau projet à l’aide de votre éditeur ou directement en ligne de commande.
Nous allons changer l’entrée de l’application qui est actuellement le fichier lib/main.dart.
Pourquoi faire cela ?
Afin de répondre aux besoins des différentes phases du projet (développement, pré-production, production ou bien même une autre configuration spécifique).
On va donc ne plus avoir qu’une seule entrée, mais plusieurs entrées.
Mais avant cela nous allons commencer par créer un fichier de configuration lib/app_config.dart dans lequel nous allons définir tous les paramètres nécessaires à l’application.
import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; class AppConfig extends InheritedWidget { final bool debug; final String apiBaseUrl; AppConfig({ @required this.debug, @required this.apiBaseUrl, @required Widget child, }) : super(child: child); static AppConfig of(BuildContext context) => context.inheritFromWidgetOfExactType(AppConfig); @override bool updateShouldNotify(InheritedWidget oldWidget) => false; }
Supposons que notre application communique avec un service web. Selon la phase auquel nous sommes, ce service web n’aura pas la même base d’URL.
Par exemple en phase de développement la base URL peut être locale (http://192.168.1.10:80/api), en phase de production elle sera (https://domain.com/api).
Il est donc judicieux d’avoir un paramètre ‘apiBaseUrl’, tout comme il est judicieux d’avoir un paramètre ‘debug’ qui indique si nous somme en phase de débogage ou non. Si c’est le cas nous allons par exemple afficher des logs en phase de développement que nous n’afficherons pas en phase de production.
Maintenant que nous avons une base, nous allons pouvoir créer nos différents points d’entrées. Mais avant, nous allons créer un fichier portant le même nom que notre projet. Ici ce sera lib/achitecture.dart.
Ce fichier contiendra le widget père de notre application qui sera stateless, car aucun changement d’état n’est nécessaire ici.
import 'package:flutter/material.dart'; class Architecture extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Architecture', home: Container(), ); } }
Nous pouvons enfin créer nos points d’entrées.
Commençons par le point d’entrée de la phase de développement que nous allons appeler lib/main_dev.dart.
import 'package:flutter/material.dart'; import './app_config.dart'; import './architecture.dart'; void main() => runApp(AppConfig( debug: true, apiBaseUrl: 'http://192.168.1.16:80/api', child: Architecture(), ));
Ici, nous importons nos class AppConfig et Architecture que nous avons précédemment créés et le package Material qui fournit la fonction permettant d’initialiser l’application (runApp), qui attend en paramètre un Widget.
Nous exécutons donc cette fonction avec une instanciation d’AppConfig en précisant les paramètres attendus par celui-ci. AppConfig étant un InheritedWidget, il attend un paramètre child qui sera rendu. Ici c’est évidemment notre Widget père.
Il vous faudra maintenant changer votre configuration de votre éditeur pour ne plus aller pointer sur lib/main.dart mais sur les configurations désirées.
Sous VSCode, ouvrez le panel de débogage (CTRL/CMD + SHIFT + D) puis en haut, vous verrez un menu déroulant avec normalement l’option « aucune configuration ». Ouvrez ce menu et cliquez sur « Ajouter une configuration ». Un fichier sera alors créé et s’ouvrira. Éditez-le de cette façon :
{ "version": "0.2.0", "configurations": [ { "name": "dev", "program": "lib/main_dev.dart", "request": "launch", "type": "dart" } ] }
Cela va tout simplement créer une configuration ayant pour nom « dev » qui lancera l’application en utilisant le fichier lib/main_dev.dart.
Vous devriez maintenant voir l’option « dev » dans le menu déroulant du panel de débogage. Si jamais ce n’est pas le cas, redémarrez VSCode.
Branchez votre téléphone et lancez l’application. Vous verrez normalement absolument rien, juste l’application qui s’est lancée et c’est normal !
Notre Widget père est actuellement vide, son rendu est un Container vide. Nous allons donc remédier à tout cela.
Récupération des données des points d’entrée
Commencez par créer un dossier lib/screens et dans celui-ci, créez un fichier lib/screens/home.dart.
import 'package:architecture/widgets/current_stage.dart'; import 'package:flutter/material.dart'; class Home extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Center( child: CurrentStage(), ), ); } }
Ce Widget se contente d’afficher le retour du Widget CurrentStageData de façon centrée.
Créez lib/widgets et ajoutez-y le fichier lib/widgets/current_stage_data.dart
import 'package:architecture/app_config.dart'; import 'package:flutter/material.dart'; class CurrentStageData extends StatelessWidget { Widget build(BuildContext context) { AppConfig config = AppConfig.of(context); return Column( mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ Container( margin: EdgeInsets.only(bottom: 16), child: Text('API BASE URL: ${config.apiBaseUrl}'), ), Text('DEBUG: ${config.debug}') ], ); } }
Quelques explications:
la fonction static ‘of’ du fichier lib/app_config.dart
static AppConfig of(BuildContext context) => context.inheritFromWidgetOfExactType(AppConfig);
prend en paramètre un context et récupère le Widget le plus proche du type « AppConfig ». Ici, c’est celui précisé dans le fichier lib/main_dev.dart.
Nous pouvons donc récupérer les valeurs spécifiées dans celui-ci et les afficher comme nous le souhaitons.
Changez maintenant lib/architecture.dart de la sorte
import 'package:architecture/screens/home.dart'; import 'package:flutter/material.dart'; class Architecture extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( title: 'Architecture', home: Home(), ); } }
Vous devriez maintenant voir l’écran suivant :
Nous allons maintenant créer le fichier lib/main_prod.dart
import 'package:flutter/material.dart'; import './app_config.dart'; import './architecture.dart'; void main() => runApp(AppConfig( debug: false, apiBaseUrl: 'https://domain_name/api', child: Architecture(), ));
Dans votre fichier .vscode/launch.json, ajoutez la configuration :
{ "name": "prod", "program": "lib/main_prod.dart", "request": "launch", "type": "dart" }
Stoppez votre processus actuel et relancez l’application avec la configuration « prod »
Vous verrez maintenant :
Vous pouvez maintenant changer en un clin d’œil de phase de développement.
Une seule petite chose à ajouter. Il vous faudra pour build, préciser le chemin vers l’entrée que vous souhaitez compiler.
Par exemple :
flutter build ios --target=lib/main_prod.dart flutter build apk --target=lib/main_prod.dart
Conclusion
Avec cette méthode il est facile et rapide de changer de phase de développement. De plus elle est très malléable et si vous avez besoin d’ajouter des paramètres, il vous suffit de les ajouter dans le fichier app_config, et de saisir la valeur dans chaque point d’entrée. Et elle ne se limite pas uniquement à dev, preprod ou prod, vous pouvez créer selon vos besoins tout type de configurations.
&nbps;
EL TIGRE peut vous apporter son expertise Flutter pour vous développer une application hybride et très performante. Faites appel à nous !