React Native est un framework développé et dirigé par Facebook, distribué en open-source (avec la licence MIT), avec une forte communauté de développeurs. Le motto de React (et donc par extension React Native qui nous intéresse ici) est “Learn once, write anywhere.” soit, un seul code pour (au moins) 2 plateformes : iOS et Android.

Les concepts de React Native étant les mêmes que React, et ce faisant, nous codons en javascript – la lingua franca du web, l’intégration d’un nouveau développeur s’en trouve facilitée.

# La prise en main est extrêmement aisée

React Native ne faisant qu’ajouter un moteur de rendu différent de React, la prise en main est extrêmement aisée lorsque l’on a déjà manipulé React JS (la librairie JavaScript dédiée pour le web).
Mais à la différence de React JS, React Native arrive avec des composants clés en main.

Ces composants proposés par React Native sont le plus petit dénominateur commun entre les plateformes iOS et Android. On y trouve principalement les composants :
– View : Simple conteneur, similaire au div HTML
– ScrollView : Conteneur, permettant de faire défiler du contenu
– Text : pour faire le rendu de texte. A contrario du HTML, tout texte se doit d’être inclus dans cette balise
– Button, TextInput, Switch : bouton, champ de saisie et case à cocher pour les formulaires. À noter que ces différents composants respectent les spécificités de style et de comportement propres à chaque plateforme, mais sont personnalisables.

Ils forment les briques de base pour des composants plus complexes.

# Il est également possible d’écrire du code natif

Ces composants ne sont pas la seule manière d’écrire une application, car il est également possible d’écrire du code natif (par exemple Kotlin chez Android et Swift chez iOS) afin de développer des éléments ou des mécanismes que React Native n’apporte pas de base. On pourra citer, par exemple, une carte géographique avec téléchargement et stockage des couches de fond sur le téléphone, un mécanisme de synchronisation de données automatique afin d’apporter une meilleure gestion offline (cf. Offline Uploader ci-dessous), … Et ainsi augmenter les possibilités offertes par React Native.

Et en vrai, à quoi ça ressemble ?

Un projet React Native se voit à l’origine très épuré. Cela commence par un premier fichier, appelé App, qui sera le portail d’entrée de notre application. À partir de là il est ensuite possible de définir les pages et composants qui serviront au sein du projet.

# Le projet est écrit une fois, et le code est interprété pour chaque plateforme

Prenons un exemple très simple :

React Native permet d’effectuer un pont entre un projet écrit en JavaScript et les modules natifs de chaque plateforme. C’est grâce à ce pont qu’existe la notion de code universel : le projet est écrit une fois, et le code est interprété pour chaque plateforme.

Une fois compilé, le rendu visuel est différent selon la plateforme utilisée :

Suivant le besoin, il est tout à fait possible de surcharger cette stylisation propre à chaque OS afin de personnaliser chaque composant et de chercher à obtenir un unique visuel pour toutes les plateformes.

Et à l’usage ?

Cela transparaît clairement dans nos retours d’expérience : une des grandes forces de React Native est sa facilité d’utilisation au quotidien.

La phase de développement est facilitée par les outils mis à disposition :

la documentation très complète et claire, agrémentée de simulateurs (via https://snack.expo.io/ ) permettant de tester en temps réel les composants.

  • la compilation à la volée, très pratique pour effectuer des tests de manière rapide et efficace sans avoir à effectuer un cycle complet de compilation
  • le rafraîchissement des écrans presque instantané via un « hot reloading » mettant à jour l’interface sans devoir redémarrer l’application
  • la gestion des simulateurs iOS et Android

La phase de maintenance est également facilitée par un suivi clair des évolutions via le github du projet et le blog, ainsi qu’un outil d’upgrade automatique de version (et l’aide d’un outils de diff pour ce qui n’aurait pas été fait automatiquement).

Et si on allait plus loin ?

La promesse de React Native, c’est qu’une unique application écrite en JavaScript peut fonctionner sous iOS et sous Android. Deux fois moins de travail, donc un coût divisé par deux ! Mais est-ce toujours aussi simple ?

Comme vu précédemment, React Native propose une base de composants officielle. Mais celle-ci ne couvre pas toutes les utilisations avancées. Pour ces cas de figure, il est possible d’écrire des modules natifs.
L’écriture d’un module natif nécessite trois développements : le code natif pour Android (Java, Kotlin), le code natif pour iOS (Objective-C, Swift) et enfin le code JavaScript qui va communiquer avec le code natif et offrir les nouvelles fonctionnalités à notre application.
On se rend alors compte que si l’application que l’on développe repose majoritairement sur des fonctionnalités qui ne sont pas offertes nativement par React Native, son utilisation peut apporter plus d’inconvénients que d’avantages.

# C’est la force de l’open source !

Heureusement, même lorsque qu’une fonctionnalité n’est pas présente nativement, il n’est généralement pas nécessaire de créer son propre module natif car d’autres développeurs s’en sont occupés avant nous et ont mis leur travail à la disposition de la communauté : c’est la force de l’open source !
On peut entre-autres citer react-navigation (navigation dans les écrans, onglets, etc.), react-native-maps (cartographie), react-native-svg (images SVG), …

Cependant, dans le cadre de l’application MesParcelles (Android & iOS), nous avons eu à développer un module natif. MesParcelles est une application pensée avant tout pour un fonctionnement hors-ligne. Les utilisateurs sont principalement des agriculteurs, et dans les champs le réseau mobile n’est pas toujours satisfaisant ! Un agriculteur doit tout de même pouvoir saisir une intervention sur une parcelle agricole dans l’application, sans avoir à se soucier de la force du signal. Et, parce que l’expérience utilisateur est primordiale, sa saisie devra se synchroniser dès que possible et de manière transparente avec les serveurs MesParcelles, lorsqu’une connexion mobile sera disponible, et ce sans avoir à lancer l’application.

Lors du développement de cette synchronisation, nous avons été confrontés à un défaut majeur de React Native : l’exécution du code JavaScript est stoppée lorsque l’application n’est pas au premier plan.

Ainsi, il n’est pas possible d’utiliser la fonction setInterval (permettant une exécution décalée de code dans le temps) comme nous pourrions le faire dans un navigateur web, afin de retenter la synchronisation à intervalles réguliers. 

Et de toute façon, ça ne serait pas forcément viable car ces dernières années, les deux plateformes ont mis en place des contraintes sur l’exécution en arrière plan, afin d’économiser la batterie du téléphone.

Après des recherches et des essais de modules natifs open source qui ne nous ont pas satisfaits, nous nous sommes lancés dans le développement de notre propre module natif, que nous avons appelé react-native-offline-uploader.

La partie native Android est développée en Java, et utilise l’API JobScheduler, qui permet de planifier des tâches selon certaines contraintes. Dans notre cas, la contrainte est la présence d’une connexion à Internet. L’OS s’occupera alors d’exécuter la tâche demandée (la synchronisation de l’intervention saisie par l’agriculteur) dès qu’une connexion (réseau mobile ou WIFI) sera disponible. Tant que ce n’est pas le cas, notre application est en veille et ne consomme pas de batterie.

La partie iOS est développée en Swift, et utilise URLSessionConfiguration.background configuré avec waitsForConnectivity = true, qui s’avère être une simple requête web qui a la particularité d’attendre que l’envoi puisse réellement s’effectuer (= que le réseau soit présent et utilisable) avant que l’appel soit lancé, et ce même si l’application est en veille/background.

Enfin, la partie JavaScript s’occupe de communiquer avec la partie native de chaque plateforme et offre 3 fonctions utilisables depuis le reste de l’application : startUpload, permettant de lancer la synchronisation ; cancelUpload, permettant d’annuler la synchronisation ; et addListener, permettant d’ajouter des écouteurs sur une synchronisation en cours (avancement, complétion, etc.)

# Retour d’expérience : nos avis personnels

Alexis Venner, Chef de projet technique
React Native est rapide à appréhender et son écriture en javascript / React permet à une équipe web de prendre en charge le développement d’application mobile native : c’est donc la même équipe qui pourra prendre en charge le développement dans le cadre de la création d’une déclinaison mobile native.
Jean-Philippe Thevenoux, Architecte & Lead tech
React Native est assez simple à prendre en main, mais dès que l’on veut gérer finement les différentes plateformes, on se retrouve avec un code un peu complexe. Les composants de base couvrent la plupart des besoins, et la customisation stylistique ainsi que les composants faits-maison sont assez simples à mettre en place. Pour une appli sur iOS et Android, ça me parait finalement un bon choix de technologie.
Léa Pitois, Développeuse Junior
React Native a été pour moi le premier contact avec le développement mobile. Et quelle bonne surprise ! Des composants simples déjà existants, la possibilité d’en créer de nouveaux, des hooks qui simplifient la vie, une documentation complète et détaillée, un code (presque) similaire pour les différentes plateformes… Bref, avec un bon mentor c’est un réel plaisir d’apprendre à développer avec React Native.
Mathieu Sanchez, Expert technique et mobile & Lead Tech
Le framework React Native n’est pas le seul lorsqu’il s’agit de développer des applications multi-plateformes (je pense à Flutter chez Google ou Xamarin chez Microsoft) mais il bénéficie de l’énorme catalogue de librairies déjà disponibles pour React (la version web). Nous pouvons ainsi répondre facilement aux demandes de fonctionnalités de nos clients.
Nabil Bouthiba, Développeur
Grâce à l’utilisation commune de javascript, la migration d’une application web en React Native est facilitée. De plus, la communauté React Native est très importante et en cas de problème React Native Inspector permet de rapidement debugger l’application.
Côté SGBD, il est possible d’exploiter SQLite qui certes n’a pas autant de fonctionnalités qu’un PostgreSQL mais offre de bonnes performances en plus d’être relationnel.
Alexandre Billon, Développeur junior
L’aspect universel de React Native permet de mettre en arrière-plan l’aspect plateforme, sans pour autant l’oublier complètement. Framework très populaire, sa documentation et sa communauté sont très variées ce qui facilite les choses lorsque l’on rencontre un souci ou que l’on cherche une fonctionnalité particulière. Cependant il est nécessaire de rester vigilant lors du développement, le fonctionnement offline impliquant certains fonctionnements particuliers.