Créez votre première application flutter backée par une API en ASP.NET

Your Content Goes Here

19/06/2023

13min

Utiliser la même base de code pour ses applications multi-devices est le graal pour un développeur. Aujourd’hui on vous présente Flutter, un framework qui vise à résoudre ce problème de manière efficace grâce à son langage Dart.

Qu’est-ce que Flutter ?

Flutter est un framework open-source de développement d’applications mobiles, web et de bureau créé par Google en 2017. Il permet de développer des applications pour iOS, Android, le web et des systèmes d’exploitation de bureau tels que Windows, macOS et Linux. Ce framework utilise le langage Dart.

L’un des principaux avantages de Flutter est sa capacité à créer des applications avec une seule base de code qui peuvent être exécutées sur plusieurs plateformes. Cela est possible grâce à l’utilisation d’un moteur de rendu personnalisé appelé Skia, qui permet à Flutter de dessiner des interfaces utilisateur en utilisant des widgets.

Les widgets sont les éléments de base de Flutter, et sont utilisés pour créer l’interface graphique de l’application. Ils sont hautement personnalisables, ce qui permet de créer des designs et des animations complexes. De plus, la réactivité de Flutter est due à son approche de programmation réactive, où les widgets sont redessinés à chaque fois que l’état de l’application change.

Le développement de Flutter a commencé en 2015 sous le nom de projet Sky, avec pour objectif de créer un framework pour le développement d’applications mobiles qui pouvait rivaliser avec les technologies existantes telles que React Native et Xamarin. En 2017, Flutter a été annoncé lors de la conférence Flutter Live, et est devenu un projet open-source avec une communauté de développeurs en constante croissance.

Depuis son lancement, Flutter a été adopté par de nombreuses grandes entreprises telles que Alibaba, BMW, Philips, eBay, etc. De plus, le framework continue de se développer rapidement, avec de nouvelles versions et des mises à jour fréquentes pour ajouter de nouvelles fonctionnalités et améliorer la stabilité.

Le langage Dart

Dart est un langage de programmation orienté objet et fonctionnel créé par Google en 2011. Il a été conçu pour être utilisé dans une grande variété de projets, allant des applications web aux applications mobiles. Il a été utilisé en interne chez Google pour le développement de certains de ses produits tels que AdWords et Google Fiber.

Le langage Dart est également connu pour sa syntaxe claire et simple, qui le rend facile à apprendre pour les nouveaux programmeurs. Il dispose d’une bibliothèque standard complète qui offre des fonctionnalités pour la gestion des chaînes de caractères, des listes, des ensembles, des cartes et plus encore.

L’un des concepts clés de Dart est l’utilisation de classes et d’objets pour encapsuler la logique de l’application. Les classes sont des modèles pour les objets, qui sont des instances de la classe. Les objets sont utilisés pour stocker des données et effectuer des opérations sur ces données en utilisant les méthodes de la classe.

En termes de programmation fonctionnelle, Dart prend en charge les fonctions anonymes et les fonctions fléchées, qui peuvent être utilisées pour simplifier les expressions lambda. Il prend également en charge la programmation asynchrone, qui permet aux programmes d’effectuer plusieurs tâches en même temps sans bloquer l’interface utilisateur.

Enfin, Dart est également connu pour sa capacité à être compilé en code natif pour une exécution plus rapide, ce qui le rend adapté pour les projets nécessitant des performances élevées.

En résumé, Dart est un langage de programmation moderne, facile à apprendre et à utiliser, offrant des fonctionnalités orientées objet et fonctionnelles, ainsi que des performances élevées.

Le concept de Widget

Les Widgets sont des éléments fondamentaux pour construire des interfaces graphiques dans Flutter. Il en existe deux types principaux: StatelessWidget et StatefullWidget.

Un StatelessWidget est un Widget qui ne possède pas d’état, c’est-à-dire qu’il ne peut pas être modifié une fois qu’il est construit. Il est utilisé pour les éléments de l’interface utilisateur qui ne changent pas en fonction des événements de l’application. Les StatelessWidgets sont construits une seule fois et ne sont jamais reconstruits. Voici un exemple de code pour un StatelessWidget :

Copy to Clipboard

Dans cet exemple, nous avons défini un widget appelé MyAppBar, qui prend un paramètre de titre et affiche une barre d’application avec un bouton de menu, un titre et un bouton de recherche. Le titre est passé en paramètre au constructeur et est affiché dans la barre d’application.

Contrairement au StatelessWidget, le StatefulWidget possède un état : il peut être modifié dynamiquement en fonction des événements de l’application. Le State<T> est une classe séparée qui gère les données et la logique du StatefulWidget. Lorsque l’état du StatefulWidget est modifié, la méthode build() est rappelée pour reconstruire le widget et mettre à jour l’interface utilisateur. Voici un exemple de StatefulWidget  :

Copy to Clipboard

Ici, nous avons défini un widget qui affiche un compteur et un bouton pour l’incrémenter. Le compteur est stocké dans l’état _CounterState et est incrémenté lorsque le bouton est pressé en appelant la méthode _incrementCounter(). La méthode build() est appelée chaque fois que l’état est modifié pour reconstruire le widget et mettre à jour l’interface.

Après avoir fait connaissance avec Flutter et Dart, passons à la création de notre application. Nous allons écrire un simple widget récupérant des articles d’occasion auprès d’une API. On partira du principe que les SDK de Flutter et Dotnet sont installés sur la machine :

L’application Flutter

Tout d’abord, il faut créer un nouveau projet Flutter :

Ouvrer votre terminal, et tapez la commande

flutter create --platform=android,web,linux client

Le paramètre –platform nous sert à spécifier à Flutter que nous souhaitons compiler notre projet pour ces différents devices. Observer la structure du projet généré

L’architecture d’un projet Flutter suit une structure spécifique qui aide à organiser le code de manière claire et cohérente. On distingue les dossiers relatifs aux plateformes ciblées (android, linux, web), le dossier relatif au code source (lib) contenant la class main.dart, le dossier relatif aux tests (test), et enfin le dossier relatif aux builds (build). On note aussi le fichier pubspec.yaml, qui serait l’équivalent d’un fichier AndroidManifest.xml sous Android.

Les dossiers relatifs aux plateformes contiennent le code source ainsi que les fichiers spécifiques aux plateformes. Il est possible d’y ajouter du code spécifique à la plateforme pour les cas particuliers ou complexes (par exemple, rajouter une classe Android native pour un besoin spécifique, ou modifier le manifest).

C’est dans le dossier lib que nous continuons la création de notre application.

Créez un nouveau dossier nommé models dans ce répertoire lib, et créez un fichier nommé article_model.dart qui représente le modèle d’un article.

Dans ce fichier, nous allons créer la classe ArticleModel qui contiendra les informations d’un article. Voici le code de la classe :

Copy to Clipboard

Cette classe contient les informations suivantes : l’identifiant, le titre, la description et l’image, ainsi que son prix.

Nous avons également défini une factory method qui va nous permettre de créer un objet ArticleModel à partir d’un objet JSON.

Maintenant, nous allons créer un nouveau dossier, nommé services, à la racine du projet. Dans ce dossier, créez un fichier nommé api_service.dart qui va nous permettre de récupérer les articles à partir de notre API dotnet.

Dans ce fichier, nous allons créer la classe ApiService qui contiendra la méthode pour récupérer les articles. Voici le code de la classe :

Copy to Clipboard

Cette classe contient une méthode getArticles qui va envoyer une requête GET à notre API pour récupérer la liste des articles. Si la requête est réussie, les articles sont convertis en ArticleModel et retournés sous forme de liste. Sinon, une exception est levée.

On note le type de retour de la méthode : un Future<T>. Les Futures sont l’équivalent des Task en dotnet, ce sont des objets asynchrones dont l’implémentation nous permet d’intéragir avec le code s’exécutant dans un autre thread.

Notez aussi l’utilisation du package http. Pour ajouter ce package à votre projet, lancez la commande flutter pub add http à la racine du projet.

Maintenant que nous pouvons récupérer nos articles, passons à la partie où nous allons afficher les articles dans notre application. Dans votre projet Flutter, ouvrez le fichier main.dart remplacez le contenu du fichier :

Copy to Clipboard

Nous utilisons un StatelessWidget : en effet, inutile de mettre à jour son état de notre home page dans cet exemple. Sa méthode build() retourne tout d’abord une MaterialApp, le widget de base nous permettant d’implémenter une application. Il nous place dans un contexte nous offrant par exemple, la taille de l’écran (nécessaire à Flutter pour construire son arbre visuel). Le Scaffold quant à lui nous permet d’implémenter la structure de base des layouts Material Design. Nous lui rajoutons dans son champ appBar une AppBar avec le titre de notre application, et dans son champ body le corps de notre application.

Pour le corps, nous utilisons un FutureBuilder qui va nous permettre de récupérer les articles de manière asynchrone tout en se mettant à jour au fur et à mesure du téléchargement des articles.

Le FutureBuilder est un widget prenant en argument un Future (souvenez vous, le Future<List<ArticleModel>> retourné par notre méthode getArticles()), et qui se reconstruit lorsqu’un évennement sur le Future occure.

Le FutureBuilder est un StatefulWidget ! Son état est mis à jour selon l’état du Future<List<ArticleModel>>, provoquant la reconstruction du widget.

Si la requête est un succès, nous les affichons dans une liste à l’aide du widget ListView.builder. Ce widget prend en argument une méthode qui sera appelée pour construire chaque élément de la liste. Pour des questions de stabilité et de simplicité, j’affiche un LogoFlutter plutôt qu’une vraie image. Mais vous pouvez remplacer ce widget par un Image.network(data[index].imageUrl), le framework se chargera d’aller la chercher et vous l’afficher 🙂

Pensez tout de même à gérer la taille en encapsulant le widget Image dans un widget tel qu’une SizedBox afin que chaque ListTile ai la même taille.

Si une erreur se produit, nous affichons un message d’erreur.

Si les données sont en cours de chargement (à savoir, un événement à lieu mais ce n’est ni une erreur, ni une transmission de datas), nous affichons un indicateur de progression.

L’API

Maintenant que nous avons créé notre application Flutter, passons à la création de notre API dotnet. Comme nous sommes peu contraints, permettons nous de la créer à la racine du répertoire client de notre application :

dotnet new webapi -n ServerApi

Notre projet devrait ressembler à ça :

Créez également un nouveau dossier nommé Models à la racine du projet de l’API. Dans ce dossier, créez un fichier nommé Article.cs

Dans le fichier Article.cs, nous allons définir la structure de notre modèle d’article. Ajoutez le code suivant dans ce fichier :

Copy to Clipboard

Notre modèle d’article contient un identifiant, un titre, une description, un prix et une URL d’image.

Maintenant, créons le contrôleur qui va nous permettre d’interagir avec les articles. Dans le dossier Controllers, créez un fichier nommé ArticleController.cs. Ajoutez le code suivant dans ce fichier :

Copy to Clipboard

Ici, notre controlleur retourne simplement une liste d’Article lorsqu’une méthode GET est exécutée sur la route “/article”.

Le test

Il est temps de tester notre application. Mais d’abord, je sais que vous l’aimez tous : la configuration !

Dans le répertoire Properties de notre API, nous devons modifier le paramètre applicationUrl du launchSettings.json :

Copy to Clipboard

Ce localhost n’est pas joignable sur depuis notre émulateur car il correspond au réseau local de notre PC. Remplacez localhost par votre nom d’hôte, ou l’IP locale de votre machine sur votre réseau (je vous conseille l’IP locale, j’ai eu plusieurs fois des soucis de résolution DNS avec l’émulateur Android).

Ensuite, retournez dans votre classe api_service.dart dans le projet Flutter, et modifiez l’URL

Copy to Clipboard

Ensuite, pour tester notre application sur Android, il nous faut une permission. Et c’est là que les dossiers relatifs aux plateformes ciblées prennent tout leur sens. Allez dans android/app/src/main, et ajoutez la permission android.permission.INTERNET dans le AndroidManifest.xml

Copy to Clipboard

Vous pouvez en profiter pour reconnaître la structure d’une application Android sous le dossier android 🙂

C’est fini, allez à la racine du répertoire de l’API et executez la commande

dotnet run

Puis à la racine de l’application Flutter, nous allons pouvoir tester nos différents supports.

Commençons par l’application Android. De mon côté, j’ai les outils de développement Android d’installés. Je lance mon émulateur avec la commande suivante

emulator Pixel_6_Pro_API_33

En listant les devices connectés, je vois sur quels devices je peux lancer mon application

flutter devices

Copy to Clipboard

En lançant la commande flutter run -d emulator-5554, flutter lance mon application sur mon émulateur Android :

https://codeinsider-wp.azurewebsites.net/wp-content/uploads/2023/10/image-2.png

En lançant la commande flutter run -d chrome, flutter lance mon application dans un navigateur :

Enfin, en lançant la commande flutter run -d linux, futter lance mon application dans une fenêtre :

Et voilà 🙂

Conclusion

En conclusion, Flutter est un framework puissant. Il est une solution simple et efficace pour créer des applications multiplateformes à partir d’une même base de code. Le langage Dart est bien dimensionné pour la création d’interfaces graphiques, la librairie flutter nous offre une multitude de widgets, et les outils intégrés au framework nous permettent de développer dans un environnement agréable et élégant. Par cet article, j’espère avoir titillé votre curiosité, et vous invite à découvrir par vous même tout ce que ce framework a encore à vous offrir !

Nous avons d’ailleurs réalisé l’application de la CCIFI avec Flutter au sein de Blue Soft