Pour aujourd’hui je vous propose une petite implémentation d’un thème sous React avec la lib Material-Ui, l’implémentation de Material Design de Google.
Je vous met mon dépot Github pour avoir le code source complet du projet.
Objectifs
Thème dark & light dans toute l’app
Système de sauvegarde des préférences utilisateurs via local-storage
Pré-requis
Il va vouloir quelques dépendances NPM tel que:
React
Material-ui
Initialisation de CssBaseline
On ajouter le composant CssBaseline en entrée de notre application. Mais à quoi set t-il ?
Il va nous permettre de remplacer certaines props CSS de base de notre app, faire certains reset. Cela va permettre d’éviter certains props de mal switcher entre Dark et Light theme.
Nous avons donc dans notre fichier root :
ThemeHandler: on va décrire ce composant juste ensuite 😉
CssBaseline: notre composant pour le bon switch dark/light
ContentApp: notre composant qui va contenir le reste de notre app
Disons qu’il fait un semblant de normalize.css, mais pour Mui 🙂
Création de la palette de notre thème
On va définir dans ce composant tout les hyperparamètre qui touche à l’aspect visuel du thème, ainsi que sa palette de couleurs.
On va définir les props suivants:
local_storage_key: string/id de la props qui nous permet de savoir le thème courant de l’utilisateur. On va détailler le local storage plus tard dans l’article
baseTheme: thème parent qui va définir les paramètres globaux qui seront utilisé à la fois pour le dark que le light
dark_theme: palette spécifique au thème dark
light_theme: palette spécifique au thème light
Création du contexte du thème
On va définir un contexte pour notre thème. Cela va nous permettre au sein de l’ensemble de notre application de récupérer des informations à propos du thème. Il va nous être important dans la suite de l’article. Pour le moment on initialise un contexte vide :
Création du gestionnaire de thème
On souhaite maintenant un système de gestion de thème. On souhaite qu’il garde l’état actuel du thème (palette dark ou light), mais aussi qu’il ait une fonction permettant de switch de thème.
Nous définissions en premier lieu un useState. Il va nous permettre de changer la valeur du thème en cours, mais aussi de la récupérer. On va l’initialiser avec le local storage de l’user. Il va nous permettre de garder la préférence de l’user dans le navigateur ( une sorte de cookie )
On init un objet de contexte avec :
isDark: boolean si le thème en cours est dark
toggleTheme: function permettant le switch de thème
La fonction toggleTheme permet de setter une nouvelle valeur du boolean, et permet de mettre à jour la valeur du local storage.
La fonction getTheme permet de retourner la bonne palette de couleurs en fonction du boolean courant.
D’un point de vue HTML, le composant ThemeHandler est composé de la sorte:
themeContext.Provider: permet de consommer une valeur par défault de context ( on la init auparavant)
themeProvider: permet de fournir un thème à notre application avec celui défini dans le context précédent
{props}: permet d’insérer les nodes enfants que l’on fournira au composant
Ajout de contenu pour notre app
Le système de switch et gestion de thème est mis en place. Il nous faut maintenant quelques composants UI avec un toggle, permettant de switch entre dark et light.
Grace au useContext, on va pouvoir récupérer le context du thème. Ceci va nous permettre de connaître le type de thème actuel au sein de notre application, ainsi que de la function pour switch de thème.
A partir de ce context, vous pouvez ajouter un bouton, un switch ou autre afin de le bind avec la function de switch de theme toggleTheme, et aussi d’initialiser votre composant avec l’état en cours via le isDark.
Vous commencez le développement mobile et vous hésitez à choisir ReactNative ou la surcouche Expo ? Je vous donne quelques indices afin d’y voir plus clair sur quel framework vous devriez choisir en fonction de vos compétences, du temps, et de vos besoins.
Code source du projet est disponible ici, sur Github.
Présentation de React
Framework pour le développement web frontend, développé par Facebook et concurrent direct de Angular et de Vue.js.
Dom Réel et virtuel
React est à la mode. Il est performant, et ce grave à un point important, est qu’il utilise un DOM (Document Object Model) virtuel.
Le DOM (réel) est l’arbre de nœuds, la représentation textuelle de toute votre application web. Quand vous effectuez un changement d’état au sein de votre application, l’intégralité du DOM est recréer. Cela comprend alors l’ensembles des éléments fils de l’application. Et ceci peut être couteux en terme de performance pour des applications grandissantes, surtout si vous y effectuez des modifications fréquentes de votre UI.
Le DOM virtuel quand à lui est un second arbre, correspondant à l’état réel de la globalité de votre application. Vous pouvez alors vous demandez, n’est-ce pas doublon d’avoir deux arbres à l’identique ? Et bien non.
On imagine que vous effectuiez une modification de couleur, sur un texte par exemple. Dans le cas d’une application avec Angular, celui-ci va redessiner la globalité de l’application. Avec React, seul le DOM virtuel va être modifié. React va alors réaliser une comparaison avec des algorithmes spécifiques entre le DOM virtuel fraichement actualisé, et le DOM réel. En fonction des différences entre les deux arbres, seul les nœuds qui ont un nouvel état, vont être redessiner dans le DOM réel. Cela permet de redessiner seulement un seul nœud, dans notre exemple.
Voici une image plus parlante :
Présentation de React Native (Vanilla)
C’est un framework développé par Facebook pour le développement d’applications cross-platform (iOS et Android).
Développement natif vs développement hybride
Le développement natif est l’utilisation de SDK spécifique. Xcode pour iOS, et Android studio pour Android.
Pourquoi favoriser le dév. natif
Le développement natif utilise ses modules et bibliothèques natives, avec son langage natif. Il sera toujours plus performant que les solutions hybrides, même si au cours du temps nous observons de moins en moins de différences
L’accès aux modules spécifique facile (notification push par exemple)
Poids des apk/ipa très léger
Pourquoi favoriser le dév. hybride
Un seul langage de développement pour deux plateformes
Un code unique. Donc 2x moins de bug, en 2x moins de temps
Une interface UI/UX identique, évitant des différences
Présentation de Expo
Expo embarque ReactNative, c’est une sorte de wrapper, de surcouche. Vous retrouvez donc l’ensemble des items graphiques de ReactNative.
En voici les principales caractéristiques :
Projet déjà configuré ! En une minute vous avez votre Helloworld de fonctionnel ! Cela évite des paramétrages en tout genre et fastidieux sous ReactNative Vanilla pour paramétrer Xcode et AndroidStudio.
Pas besoin de mac pour tester votre app sur les deux OS mobile ! Et ça, ça fait plaisir. Ayant un vielle Iphone et mon Android de tout les jours, je peux tester via l’application Expo (disponible sur les stores iOS et Play), avec hot-reload, et sans avoir de Mac, l’application que je développe sur mes deux smartphones. Même si le dév. hybride promet d’avoir un UI/UX 100% identique entre les deux plateformes, il m’est arrivé que mes checkbox ne s’affichait pas correctement sur iOS. J’ai donc forcé pour mes deux plateforme, l’utilisation de la checkbox Android. Soucis auquel je me serais rendu compte une fois seulement uploadé sur les stores. Sous ReactNative Vanilla, vous pouvez seulement tester sur votre iOS si vous tournez sous macOS, et seulement sur votre Android si vous êtes sur Windows pour développer.
Pas besoin de mac pour builder votre app ! Vous pouvez utiliser les serveurs expo pour cela. Attention, il vous faudra obligatoirement un compte développeur chez les deux sociétés, et acheter la licence qui va avec. Autre piège, votre build se fera à distance et non en local, attention donc si vous développer une app qui doit rester à l’abris des regards.. Mais dans tout les cas si vous souhaitez build en local et sans mac, vous pouvez utiliser une VM sous macOS Catalina avec QEMU/KVM sans soucis. Sous ReactNative Vanilla il vous faudra forcement les deux OS pour builder sur les deux plateformes, mais qui se résous aussi bien par la VM.
Accès à l’ensemble des modules natifs compliqué voir impossible… A un moment donnée, votre application grandissante va prendre en fonctionnalités. Etant donnée que Expo est une surcouche, l’accès aux modules natifs n’est pas possible pour réaliser certaines fonctionnalités. Je prends comme exemple connu comme les notifications push, ou achats-in app. Vous n’y aurez simplement pas accès.
… mais vous pouvez Ejecter Expo ! Vous pouvez cependant ‘éjecter’ Expo pour palier au problème précédent. Mais à en lire certaines expériences sur le net, selon la taille et le versionning de votre projet, que ça puisse très bien se passer comme mal se passer.
Poids supérieur des apk/ipa ! J’ai publié sur les stores ma première application avec des fonctionnalités très simple. Elle fait 50mo à télécharger sur les stores.
Quel framework choisir au final ?
Vous débutez sur le développement mobile ?
Oui ? Foncez sur ReactNative + Expo
Votre application requiert des accès natifs à des modules particuliers (achats in-apps ou push-notifications) ?
Oui ? : Foncez sur ReactNative vanilla
Non ? : Foncez ReactNative + Expo
Si votre choix se confirme à développer sous Expo, je vous propose de commencer par le premier chapitre, afin d’installer l’environnement de développement. Hello World sur mon smartphone en moins d’une minute garantie ! 😉
Nous avons vu dans le chapitre précédent comment stocker en local des données simples.
On va s’attarder cette fois-ci à comment stocker des informations plus nombreuses, plus complexes et ce de façon plus ordonnée, en utilisant des bases de données SQL.
On va réaliser une simple to-do app, avec possibilité d’ajouter une note, ou d’en supprimer, avec une liste permettant de toute les afficher.
On ne peut utiliser n’importe quel outils pour persister des données car nous sommes sur un projet Expo, nous empêchant d’accéder aux modules natifs de iOS et Android. SQLite est un moyen fonctionnant avec des projets Expo.
Objectifs
Stocker localement des informations via une base de donnée SQL
Prérequis
Installez le package pour utiliser SQLite :
expo install expo-sqlite
Nous l’importerons dans nos fichiers de la manière suivante :
import*asSQLitefrom'expo-sqlite';
Base de données & CRUD
CRUD : diminutif correspondant aux requêtes basique, à savoir Create, Read, Update et Delete.
Création de la base de données
Rien de plus simple, une seule ligne suffit :
On donne un nom à notre base, en argument. Celle-ci n’est crée qu’une seule et unique fois. Si on rappelle cette même méthode, on récupère la base de donnée crée auparavant, aucun risque de doublon.
Création de la table NOTE
On va maintenant créer notre table. Je vous montre la façon la plus simple de réaliser des transaction SQL vers notre base :
Requête SQL des plus basique avec le mot clé CREATE TABLE. On lui donne un nom de table, ainsi que la définitions de nos colonnes. Un ID auto-incrémenté pour garantir l’unicité de nos données, ainsi qu’un attribut TEXT qui contiendra le contenu de nos notes.
Nos deux attributs ne peuvent être null, et on leur défini un type, soit Text ou Integer.
Optimiser les requêtes
Je préfère une autre annotation que la précédente pour questionner la base de données, récupérer nos objets et leurs affecter des transformations. Je trouve plus clair et simple à l’utilisation. On définit notre modèle de requête avec une promesse :
On pourra utiliser ce modèle dans des fonctions async, via un appel par un await. On pourra utiliser des then() et catch() à l’appel du service dans nos vues, permettant par exemple d’afficher à l’utilisateur dans une popup si une note à bien été ajouté ou si dans le cas inverse afficher un message d’erreur avec son origine.
Récupérer toute les notes
On définit une interface pour les objets que l’on va récupérer en base. Cela nous facilitera leurs manipulations au sein de notre application :
On fait appel à notre modèle pour questionner la base :
On récupère nos objets via la requête. On va itérer sur notre résultat de requête pour re-typer correctement nos objets.
Ajouter une note
Seule différence, on va ici passer en argument le contenu de ma note que l’on souhaite persister en base. Pas besoin de lui passer un ID pour la note, car celle-ci est généré automatiquement en base. Nous avons défini cette option tout à l’heure, lors de la création de la table.
Supprimer une note
Quasiment identique au point précédent, sauf qu’ici on lui passe un ID de note à notre fonction, étant donné que c’est l’attribut qui défini l’unicité de mes items dans ma table NOTE :
Récupération des items dans la vue
Nous venons de créer notre base ainsi que des opérations CRUD permettant d’interagir avec elle. On va désormais créer une nouvelle vue, avec un champ de texte permettant de donner du contenu à une note, un bouton pour ajouter cette note, une liste scrollable permettant de naviguer sur l’ensemble de nos notes en base, et leur associé à chacun un bouton pour les supprimer.
Définition du state de notre vue
On commence par créer le squelette de base de notre vue :
On utilise ici un composant de classe et non un composant fonctionnel. On a besoin d’utiliser un state pour l’affichage dynamique du contenu de notre liste scrollable. On défini un attribut myNoteList correspondant à une liste de l’ensemble de nos notes en base, ainsi qu’un second attribut note correspondant au champ de texte remplissable par l’utilisateur pour créer une nouvelle note. On initialise les deux attributs dans le constructeur.
Définition des méthodes de notre vue
On défini les méthodes pour mettre à jour nos éléments, pour ajouter une note, ainsi que la supprimer :
La méthode componentDidMount() est une méthode standardisé de React, permettant d’être appelé une seule et unique fois et ce à la fin de la création du composant. On lui demande à l’ouverture de notre page, d’initialiser notre liste avec le contenu de notre base de données.
Définition des éléments visuels de notre vue
Ici rien de bien complexe. J’ai créer un titre de page, un champ de texte avec un bouton pour ajouter une note. Une liste scrollable présentant l’ensemble des notes en base, ainsi qu’une option permettant de les supprimer :
J’ai utilisé des icones Ionicons inclus dans Expo, qui s’adapte en fonction de si vous êtes sur Android ou iOS via la méthode Platform.OS, encapsulé dans des TouchableOpacity, pour rendre un peu plus esthétique mes boutons d’interactions, ainsi que des flexbox pour avoir une touche de responsive design.
Conclusion
Vous venez de voir comment créer très simplement une base de donnée pour votre application React Native tournant sous Expo, comment l’interroger et surtout comment récupérer et afficher le résultats dans une belle vue responsive.
Nous venons de voir au chapitre précédent comment organiser une navigation complexe et imbriquée pour une application avec une architecture grandissante.
Nous allons voir aujourd’hui comment stocker des données plutôt simple, par exemple des paramètres de l’application comme l’activation ou non d’un thème clair ou sombre.
On ne peut utiliser n’importe quel outils pour persister des données car nous sommes sur un projet Expo, nous empêchant d’accéder aux modules natifs de iOS et Android. AsyncStorage est un moyen fonctionnant avec des projets Expo.
AsyncStorage nous permet de persister des données en local sur le smartphone, de façon asynchrone et non crypté. Les informations sont sauvegardé en clair, donc éviter de stocker des données sensibles tel que des mots de passes.
Le stockage s’effectue sous forme de couple tel quel : <Clé, Valeur>.
On ne peut stocker que des string, donc pour des éléments plus complexe tel que des objets, on devra utiliser JSON.stringify() pour la conversion en JSON lors de la sauvegarde d’une donnée, et utiliser JSON.parse() pour lire un objet.
Sauvegarder des données
Pour un string
Pour un objet
Lire des données
Pour un string
Pour un objet
En pratique
On va faire un exemple tout bête, à savoir charger le nom d’un utilisateur à l’appui d’un bouton.
Méthode d’écriture & lecture de donnée
On commence par définir nos deux méthodes pour charger et sauvegarder une donnée :
On appellera la méthode initProfileName() dans l’entrée de notre l’application (App.tsx) pour initialiser notre donnée.
Mise à jour de notre vue
On crée un état initialisé à ‘Invité’. On aura une méthode appelant notre fonction pour lire notre donnée via AsyncStorage, définit précédemment. Et enfin une méthode render() pour afficher un champ de texte, et un bouton bindé avec la fonction de chargement de notre donnée locale :
Conclusion
On vient de voir comment stocker des informations simple en local. Nous allons voir au prochain chapitre comment stocker des informations plus complexe et surtout en quantités plus importantes.
Nous venons de voir dans le chapitre précèdent comment faire une barre de navigation principal. Mais comment faire si nous souhaitons naviguer dans de nouveaux composant à travers nos vues actuelle ?
Pour réaliser une navigation imbriqué de vue dans d’autres vues, nous allons ajouter un nouvel élément, une StackNavigation.
Pour faire de la navigation imbriquée, il va nous falloir dans une première partie créer un nouveau composant, une nouvelle page. Faisons une nouvelle page Profil, qui affiche mon prénom, par exemple :
Mise a jour des ROUTES
On va ajouter une nouvelle route dans notre constante globale des routes, amenant à notre nouvelle vue précédemment crée :
Création de la stack navigator
On va créer notre composant qui va gérer la navigation par pile. On doit lui définir nos deux composants (nos deux vues), leurs routes respectifs pour y accéder, et la route initiale lorsque le composant est crée :
Mise a jour de notre tab navigator
On va désormais fournir à notre navigation par tab, non plus mon composant WelcomePage comme initial, mais directement notre stackNavigator, crée précédemment :
Appel du changement de route par un bouton
On met à jour notre composant WelcomePage, via la méthode onPress, qui est appelé lors d’un clique sur notre item, permettant d’appeler le changement de vue en lui donnant la route que l’on souhaite. Je vous montre comment faire cet appel selon le type de composant que vous utilisez au sein de votre application :
Navigation via composant fonctionnel
Navigation via composant de classe
Conclusion
Nous venons de voir comment naviguer à l’infinie entre nos vues. Dans le prochain chapitre, nous nous attarderons à comment sauvegarder, à la fermeture de notre application, des données simples, comme des paramètres de l’application.
On va vu dans le chapitre 1 comment afficher un HelloWorld!, puis dans le chapitre 2 comment générer nos installeurs. Maintenant que l’on est capable d’utiliser notre application du code à notre smartphone, on va commencer le développement.
Objectif
Initialiser une petite architecture
Créer plusieurs écrans en affichant un titre différent
Créer une barre de navigation qui switch entre elles
On va devoir commencer à réfléchir à la structure de notre projet. En effet, nous codions toute l’app dans le même fichier auparavant. On va ajouter cette fois ci de nouveaux composants, et ça risquerai de faire plutôt brouillon par la suite de notre tutoriel. Je vous propose celle-ci :
Voici un squelette de base que j’utilise couramment pour débuter une application ReactNative. Quelques explications concernant leurs utilités :
– Service : dossier donnant des services à l’utilisateurs. Générer un pdf, initialiser des paramètres à l’ouverture de l’application, etc.
– Page : contient nos vues globales, affiché tel qu’elle à l’utilisateur
– Navigation : définit l’ensemble des éléments permettant de naviguer entre les vues (tab navigator, stack navigator, etc.)
– Database : contient l’ensemble des requêtes pour questionner une base de données SQL
– Shared : éléments utilisé à travers toute l’application, que ça soit des énumérations, constantes ou interfaces
– Assets : contient des images, des polices, et tout autre éléments ‘brut’ nécessaire pour remplir notre application
– Scripts : permet d’automatiser des tâches, comme le build des ipa ou apk
– Component : contient les différents composants de notre applications, avec une granularité concernant leurs tailles (Atome => Molécule => Organisme => Template )
App.tsx : Point d’entrée de notre application
App.json : fichier de configuration global de notre application
Package.json : contient l’ensemble des dépendances de notre app (paquets npm)
Biblio requises
Il nous faut de belles icones :
npm install --save @expo/vector-icons
Il nous faut notre lib de navigation, inclus depuis react :
Pour chaque écrans que l’on aura besoin, nous allons juste y inclure au milieu un texte, pour démontrer que l’on change bien d’écrans en naviguant. Je créer des interface minimaliste avec le code suivant :
Je le fais à l’identique pour mes deux autres écrans. Tout se passe dans le dossier /scenes/.
Définition de notre barre de navigation
Premièrement, on définit via la méthode createBottomTabNavigator(), une instance
On export le type MainTabNavigator()
On créer un <NavigationContainer>
On créer <Tab.Navigator>
Dans ce dernier on définit autant de <Tab.Screen> que nous souhaitons d’écrans. On lui fourni un nom, et un composant à afficher. Rappelez vous, ce sont les écrans définit précédemment via <View>
Le tabBarOptions nous permet de définir une couleur différente selon l’onglet qui est actuellement ouvert.
Ajout d’icone
Afin de rendre notre barre plus jolie, on va y ajouter des icones au dessus de nos écritures. Pour cela on va ajouter une nouvelles propriétés à la suite de tabBarOptions, dans le Tab.Navigator :
La propriété route nous permet d’assigner la bonne icone à la bonne page.
La propriété Platform.OS nous permet de savoir si nous sommes sur un iOS ou Android, permettant d’assigner la bonne icones selon les codes de bonne conduite UI/UX de chaque constructeur.
Ajouter notre tab barre au lancement de l’application
On ajoute simplement notre composant MainTabNavigator dans la fonction principale de notre App :
Soucis de superposition de status bar
Dans certains cas, il se peut que votre application déborde sur la status bar, engendrant des données au niveau de l’horloge ainsi que sur les icones de vos notifications. Pour régler ce problème, on va encapsuler notre MainTabNavigator, par une SafeAreaView :
Chargement local de fonts
J’ai déjà eu des soucis concernant certains texte qui étaient coupé au sein de mon application, lorsque je rendais le texte en gras. En me baladant un peu sur la toile, j’ai trouvé une petite soluce, qui consiste à charger une nouvelle font pour toute mon application, en local. Dans votre dossier Assets/, rajoutez un dossier Fonts/. Ajoutez y la police que vous souhaitez, je prends pour exemple la police Arial.
Installez le module correspondant :
expo install expo-font
On commence par définir nos variables dans le fichier d’entrée globale de notre application :
Je transforme notre composant de fonction en un composant de classe. Cela va nous permettre de définir un attribut nous permettant de savoir quand notre police sera chargé :
J’initialise le constructeur de la classe App :
On utilise la fonction componentDidMount(). Celle-ci est une routine appelé une seule fois la construction de la classe, et permet de lancer des fonctions une seule et unique fois durant tout le cycle de vie de l’application :
Elle appellera ma fonction ou je lui demande de charger ma police en local, et de mettre à jour ma variable fontsLoaded.
Le dernier changement consiste à laisser l’utilisateur patienter sur le splashscreen, tant que la police d’écriture n’est pas chargé. Une les assets voulu chargé, on lance notre application :
Faîte comme suit pour utiliser notre nouvelle police fraichement installé :
Conclusion
Nous venons de construire notre barre de navigation principale de notre application.
Je vous montre au prochain chapitre, comme faire de la navigation imbriqué avec des StackNavigator. Cela permettra d’ajouter autant de vue que l’on souhaite à travers nos onglets de notre barre principale.
Vous pouvez utiliser directement Expo pour lancer très facilement votre build sur leurs serveurs distants, avec la simple commande :
expo build:android
Pourquoi je ne l’utilise pas ?
Car lorsque que j’ai voulu lancer un build, leurs serveurs étaient down, laissant mon build en attente. Flemme de perdre plus de temps, je me suis lancé dans les recherches afin de savoir si l’on pouvait nous même générer notre build. C’est un peu plus tricky, mais ça marche.
A SAVOIR AVANT DE SE LANCER DANS LE DEV MOBILE
Je souhaite vous parler de compte développeur. ça vous évitera toute surprise comme j’ai pu avoir en développant ma première application sur les stores.
Si vous souhaitez distribuer votre application sur les stores :
iOS : Compte développeur nécessaire ( 100€ par an )
Android : Compte développeur nécessaire (25€ à vie )
Avec une licence, vous pouvez ensuite lancez autant d’application que vous le souhaitez, vous n’êtes pas limité en nombre.
Si vous souhaitez seulement builder votre application en local :
iOS : Compte développeur toujours nécessaires, sur un macOS exclusivement. Vous ne pouvez générer votre certificat, teamID et votre fichier de provision en local par vous même.
Android : Pas besoin de compte spécifique. Juste un macOS ou Linux d’obligatoire. Car votre fichier de clée nécessaire au build est générable en local, par vous même.
Prérequis
Bash
NodeJS
Build pour Android
macOS ou Linux ( pensez à avoir une VM )
JDK/JRE (Java Development kit) en version 8 exclusivement
Build pour iOS
macOS
Xcode (minimum v11.4)
Fastlane ( préférez l’installation par Homebrew, le plus simple et rapide moyen )
Si comme moi vous êtes pauvres et n’avez pas de macbook pour build votre .IPA, je vous ait fait un article qui vous sauvera un ou deux jours de recherche et de test pour avoir un macOS Catalina sur votre linux qui est proche d’avoir les performances d’une install native ! Oubliez windows, oubliez virtual box ou vmware. Même mon pc à 4000€ ne fait pas tourner macOS, car aucun de ces softs ne peut attribuer des ressources graphiques, entrainant de gros ralentissement lors de vos déplacement de souris et ouverture de logiciel. Bref, c’est inutilisable, à moins de passer par mon tuto qui utilise le combo QEMU/KVM, et qui fait tourner lui Catalina facilement sur mon portable à 2 coeurs de 2015 😁
On utilisera la TurtleCLI pour générer le build. Installez le via npm :
npm install -g turtle-cli
Signature de l’application
Android
La première étape consiste à signer l’application. Cela permet de créer des certificats concernant la sécurité, pour la distribution. On va utiliser l’outil keytool de java pour générer notre keystore :
Vous pouvez apercevoir aussi des clés avec l’extension « .keystore ». C’est une clée comme les « .jks » avec un format différent.
Cette commande va vous demander plusieurs questions vous concernant :
Un fichier va être crée. Veillez à bien mettre de côté de fichier. Il vous sera demander à chaque build de votre application
iOS
Il vous faudra un certificat, un apple Team ID, et un fichier de provision
Génération du certificat
Allez sur votre compte développeur Apple. Dans l’onglet certificat, cliquez sur le bouton + :
Choisissiez l’option iOS Distribution (app store and ad hoc ) :
Faîte continuer, et on arrive sur une nouvelle fenêtre nous invitant à envoyer un fichier CRC :
On va devoir générer un certificat. Pour cela, lancez l’application Trousseaux d’accès qui est dans le dossier Applications/Utilitaires de votre macbook. Dans le menu en haut à gauche, cliquez sur Trousseaux d’accès, puis sur Assistant de certification, puis sur Demander un certificat à une autorité de certificat :
Remplir les champs demandé, et faîte enregistrer en local :
Vous aurez un nouveau fichier sur votre bureau :
On retourne sur le compte développeur Apple ouvert précédemment, nous étions rester sur la fenêtre ou on nous demander notre fichier CSR. C’est le fichier que nous venons de générer sur le bureau que nous allons upload :
Nous pouvons désormais télécharger notre certificat ! Téléchargez le, et ouvrez le :
Il sera automatiquement ajouté à notre trousseau d’accès, attaché à notre session :
Sélectionnez votre certificat fraichement installé avec sa clé privée, et exportez les deux éléments :
Exportez au format .p12, et donnez lui un nom et mettez le de côté, ce fichier vous sera obligatoire pour builder :
Un mot de passe sera demandé, notez le bien de côté, il vous le sera demandé lors du build :
Vous avez maintenant un certificat au format .p12 sur votre bureau. Gardez le bien de côté.
Création du teamID
On revient sur le compte développeur Apple, et on va allez cette fois ci dans l’onglet Identifiers, cliquez sur + :
On coche App IDs, et on continue :
On sélectionne App, et on continue :
On remplis le champ Description qui est le nom de l’application, ainsi que son bundleID sous la forme recommandé. Dans Capabilities, vous cocherez les accès et autorisations que votre application à besoin. Par exemple si c’est une application photo, elle devra avoir accès à l’APN du smartphone. Vous cliquez ensuite sur Continue, puis Register :
Notez bien votre App ID Prefix, qui est votre Team ID. Vous en aurez besoin pour build par la suite.
Fichier de provision
Troisième et dernière étape. On va maintenant s’occuper de générer du fichier de provision, lui aussi nécessaire pour buid l’application.
Toujours sur notre compte développeur Apple, on va sélectionner cette fois ci l’onglet Profiles, et cliquer sur + :
On sélectionne ensuite App store, dans l’onglet Distribution. A savoir, les builds Ad Hoc ne sont pas pris en charge par Expo. On clique sur Continue :
Sélectionnez l’app ID précédemment crée, et faîte Continue :
Sélectionnez le certificat précédemment crée, et faîte Continue :
Donnez un nom à votre fichier de provision, et faîte Generate :
Téléchargez le, et gardez le de côté, vous en aurez besoin pour générer votre build :
Export de l’application
Android & iOS
La seconde étape consiste à exporter notre application. Cela permet de créer les bundles (iOS & Android) à partir des fichiers javascript. Vous devriez apercevoir la création d’un dossier « dist » dans votre répertoire courant via la commande suivante :
Attention à utiliser la bonne, selon si votre application contient du HTTP ou HTTPS.
Servir l’application
Android & iOS
On va maintenant lancer notre application à partir du bundle crée précédemment, en local. Pour cela on va utiliser python. Déplacez vous dans le dossier « dist » précédemment crée, et lancer la commande suivante :
Vérifiez bien que le serveur tourne, via curl, ou en lançant une connexion à votre localhost via votre navigateur :
Build l’application
Dernière étape, on va pouvoir lancer le build de nos fichiers. Revenez à la racine de votre projet et ouvrer une autre console.
Android
Lancez la commande suivante pour lancer le build via turtle-cli :
Voilà votre fichier APK, situé dans le répertoire annoncé dans la console.
iOS
Lancez la commande suivante pour lancer le build via turtle-cli :
Soucis fréquemment rencontré
EACESS permissions denied
Vous pouvez vous confronter à des erreurs d’accès aux fichiers pour installer des packets npm globaux ( pour turtle-cli ou encore expo ). Oubliez les sudo su et sudo en tout genre, qui m’ont fait juste galérer encore plus. Vous pouvez fix cela en deux étapes :
Utilisez l’option ‘–unsafe-perm‘ de NPM
Pour le dossier ‘lib/node_modules’ qui résisterait aux erreurs, passez un coup de chown -R votreNomUser pour donner accès à votre utilisateur courant de la session au dossier en lecture et écriture.
Conclusion
Nous venons de générer nos fichiers d’installation APK pour Android et IPA pour iOS, afin de distribuer notre application.
On s’attaque à la navigation entre plusieurs écrans sur notre prochain chapitre.
Nous avons des outils dans le développment web, permettant de développer rapidement un squelette de base pour une application :
CLI pour Angular
CRA pour React
CLI pour React Native
Mais pour créer mon premier projet pour découvrir ces technos mobile, je pars non pas sur ReactNative CLI, mais sur ExpoCLI. C’est comme Rails mais pour ReactNative, ou encore Phonegap pour Cordova. Il étends les fonctionnalité de ReactNativeCLI.
Qu’apporte t-il de plus par rapport à React Native CLI et quand l’utiliser ?
Avantage :
Pas besoin d’Android Studio ni de Xcode
Configuration bien plus simple & rapide ( hello world en moins de une minute )
Hot reload, sur smartphone physique et non par simulateur. Oui, via l’appli Expo, vous pouvez tester votre app sur votre smartphone iOS ou Android physique, et ce instantanément. En react native vanilla, vous avez droit au simulateur Android sur Windows, et simulateur iOS sous macOS exclusivement.
Inconvénient :
Poids de l’apk/ipa, du à l’ajout de librairie annexes (~50mo le hello world, ça fait mal…)
Accès aux modules natifs impossible. Vous ne pouvez ajouter de lib natif via Xcode ou Android studio, car tout est packagé via le sdk Expo. Certaines fonctionnalité sont impossible d’être utilisé, comme les achats in-app ou le bluetooth.
En résumé, pour débuter le dév mobile ou pour de simples application, vous devriez commencer par Expo. Pour des utilisateurs expérimentés ou souhaitant des fonctionnalités spécifiques à chaque plateforme, partez sur du ReactNative vanilla.
Prérequis
Il vous faudra de base :
NodeJS
Installez ensuite la CLI de Expo via une console :
npm install -g expo-cli
Pensez à avoir Python dans vos variables d’environnements, au risque d’avoir une erreur d’installation.
Initialisation du squelette
On initialise une nouvelle application via la commande :
expo init "Nom_de_votre_app"
Vous aurez l’architecture suivante :
assets/ : dossier contenant vos images
app.json : fichier de configuration du projet
app.tsx : fichier d’entrée de votre application
package-json : contient l’ensemble des dépendances et scripts du projet
tsconfig.json : fichier de configuration de typescript
babel.config.js : fichier de configuration pour la gen du bundle ( une sorte de webpack )
Lancement du serveur de dév
Simple :
npm start
Un nouvel onglet dans votre navigateur va s’ouvrir, vous proposant divers options :
Pour faire fonctionner le simulateur Android ou iOS, vous allez devoir installer les biblio natives. Mais on peut éviter cela en utilisant notre propre smartphone. On va devoir connecter notre smartphone au même réseau wifi que l’ordinateur sur lequel on développe.
Installez l’application EXPO, disponible sur l’iOS Store et GooglePlay store, selon votre type de device. Une fois l’application lancé sur votre smartphone, vous allez pouvoir scanner le QR code affiché sur la console, comme montré sur la capture d’écran précédent. Cela va permettre de transférer le bundle directement sur le smartphone.
Vous allez pouvoir ainsi voir vos modification en temps réel sur votre téléphone, de l’application que vous codez, à chaque sauvegarde.
Icone & Splash screen
Vous pouvez changer l’icone de votre application via le fichier « app.json ».
De même pour le splash screen, qui correspond a l’image qui sera affiché le temps que votre application soit chargé par votre smartphone.
Conclusion
Nous venons de voir comment réaliser un « HelloWorld » en quelques minutes, et ce directement sur notre smartphone.
On discutera dans le prochain chapitre sur comment générer les fichiers APK et IPA, permettant d’installer et de distribuer notre application.