Articles

Après vous avoir présenté les différentes solutions existantes pour la création d’applications mobiles multi-plateformes dans un précédent article. Nous vous proposons dans cette article un retour d’expérience, de certaines solutions pour créer des applications multi-plateformes, appliqué à une problématique technique concrète.

Dans le cadre d’une étude technique récente nous nous sommes demandé comment exécuter du code natif dans le cadre d’une application mobile cross-plateforme.

Qu’entend-t-on par « code natif » ?

Par code natif on entend : un code très souvent développé dans un langage bas niveau (proche de la machine) tel que le C++. Ce type de code est employé principalement pour répondre à des contraintes de performance ou d’accès à des composants spécifiques tels que la mémoire ou la carte graphique. Bien que l’utilisation de code natif soit fréquente lors d’un développement iOS avec le langage Objective-C, cette tendance est peu commune sur Android avec le langage Java.

L’introduction récente par Apple du langage Swift et l’utilisation de Java sur Android tend à limiter l’utilisation de code natif afin de simplifier le développement en déléguant à la machine les problématiques de gestion de la mémoire.

En quoi exécuter du code natif dans une application mobile multi-plateforme est une problématique ?

Cette question est tout à fait légitime car les outils de développement proposés par Google et Apple permettent ce type d’exécution, rien ne semble donc freiner cette possibilité. Cependant dans le cadre d’un développement mobile multi-plateformes l’utilisation d’un Framework tend à organiser le développement autour d’un langage haut niveau, tels que C# ou Javascript, et ce afin de faciliter la génération de code spécifique. C’est pourquoi il est moins trivial d’appeler un code natif lorsque le langage utilisé n’est pas C++.

Indépendamment d’un développement multi plateformes comment développe-t-on du code natif pour mobile ?

Sur la plateforme iOS le code natif se présente de diverses manières il peut être proposé via une librairie dynamique (fichier .dylib), un module objective-C (fichier .mm) ou encore une librairie statique (fichier .a).

Sur Android il faut passer par le Native Development Kit (NDK) pour compiler la librairie en fichier .so (librairie dynamique unix). Ensuite il faut effectuer une liaison (binding) via l’interface java native (JNI) entre la librairie dynamique et le code Java métier.

Ce que l’on a cherché à valider

Lors de notre étude technique nous avons cherché à valider l’exécution de code natif via divers frameworks de développement multi-plateformes (Unity, React-Native et Xamarin). Le code natif que nous avons cherché à exécuter se veut très simple : une fonction qui effectue une somme ou une fonction qui retourne une chaine de caractères. Nous avons chercher à exécuter une fonction simple afin de nous concentrer sur la problématique d’appel.

La fonction est encapsulée dans une librairie native que nous aurons compilée via le compilateur C++ adéquat de la plateforme cible.

 

En pratique

Dans cette section nous allons voir comment nous avons réussi à appeler du code natif à partir des différents frameworks ciblés.

1. Unity

Pour les outils, tout se passe avec les IDE Unity et MonoDevlop.

Unity étant destiné au monde du jeu vidéo, il est donc nécessaire de créer une scene (environnement 3D) associé à un asset de type script (C#).

Ensuite il faut ajouter au projet sous forme d’asset les librairies. Pour Android les fichiers .so dans le dossier Plugins/Android/<ABI>/fichier.so et pour iOS Plugins/iOS/fichier.mm et les configurer comme suis :

 

 

Enfin il suffit de charger la librairie en associant une directive de compilation et une directive P/Invoke.

Une fois les fonctions exposées de manière statique il suffit de les appeler dans le code.

La génération de code JNI est transparente avec Unity, néanmoins la compilation des librairies se fera en dehors du projet.

 

1. React-Native

Au niveau des outils, React-Native ne propose pas d’IDE dédié il faudra passer par un éditeur/IDE supportant au minimum ES6 et au mieux ES6, Java, Objective-C.

Pour React-Native l’appel de code natif sera moins trivial que pour Unity il sera d’abord nécessaire de passer par un outil intermédiaire (Djinni) qui va automatiser la compilation du code C++ et la génération de module (iOS) / code JNI (Android).

Ensuite contrairement à Unity il faudra développer les ponts (bridge/binding) entre le code généré par Djinni et le code généré par React Native.

Enfin dans le code javascript React-Native il suffira de charger le module via le package React-Native NativeModules.

 

 

 

 

 

3. Xamarin

En utilisant la dernière version de Visual Studio (PC/Mac) il suffira de créer un projet Xamarin.Forms afin de cibler plusieurs plateformes mobiles.

A partir de ce projet il sera nécessaire de créer dans chaque sous projet cible créé par Xamarin un DependencyService qui implémente une interface définit dans le projet global Xamarin. C’est ensuite dans les implémentations cibles que l’appel à une librairie native se fera, via une directive P/Invoke. Le projet global lui ne fera que des appels de haut niveau en demandant l’interface et non l’implémentation.

 

La compilation des librairies se fera en dehors du projet Xamarin pour Android, pour iOS il faudra ajouter une directive de compilation au projet.

 

Retour d’expérience

Comme on a pu le voir au cour de ce dernier article nous avons obtenu un résultat concluant sur chacune des plateformes avec tous les frameworks testés.

Pour arriver à un résultat avec Unity il nous aura fallu moins d’un jour, une des difficultés rencontrées a été d’utiliser ce frameworks (et ses outils) dans un contexte indépendant du jeu vidéo.

React-Native est clairement l’exemple le plus clé en main que nous ayons produit lors de cette analyse, la génération du code pour une plateforme cible générant également la librairie dynamique. Cependant cette simplicité est coûteuse en temps de configuration (1.5 jour pour arriver à un résultat), nous avons du créer des bindings parfois complexes pour obtenir un tel résultat. De plus, la documentation étant actuellement limitée, aller plus loin que le simple exemple de faisabilité pourra prendre un temps non négligeable.

Avec Xamarin la réalisation d’un exemple aura été assez rapide (1/2 journée) néanmoins la compilation des librairies iOS avec le projet Xamarin n’a pas été évidente à mettre en oeuvre.

 

Pour aller plus loin

Les projets Unity/React-Native/Xamarin réalisés lors de cette analyse sont disponibles en open source sur notre compte github : https://github.com/smartorigin/Cross-platform-mobile-development-samples N’hésitez pas à les manipuler/tester, des README sont là pour vous aider dans la configuration/prise en main de ces différentes technologies.

Smart/Origin vous accompagne dans la création d’applications mobiles innovantes, de l’étude de faisabilité à la livraison sur les différents store.

 

Article rédigé par Marc-Alexandre Blanchard.

Récemment nous avons été conduits à réaliser une étude sur l’utilisation de code natif dans une application mobile qui cible plusieurs plateformes. Dans cette série de deux articles nous allons revenir sur la notion de développement multi-plateformes mobiles dans un premier article, avant de présenter dans un deuxième article, un retour d’expérience, via divers exemples permettant d’utiliser du code natif dans une application mobile multi-plateformes.

La présentation qui suit ne se veut pas exhaustive, elle présente les points que nous avons jugés clés pour comprendre les principes abordés dans le deuxième article.

Avant de définir ce qu’est une application multi-plateformes rappelons quelles sont les principales plateformes mobiles et lesquelles se doit-on de cibler lors du lancement d’un nouveau produit mobile.

Les principales plateformes mobiles

Le monde de la téléphonie mobile (en 2017) est représenté par deux acteurs principaux qui se partagent la quasi totalité du marché : Google avec Android (87.8% par de marché) et Apple avec iOS (11.5%) (source Gartner Novembre 2016). La force principale des systèmes d’exploitations Android et iOS est leur extensibilité via un écosystème applicatif ouvert aux entreprises et créateurs externes. Ces applications sont alors disponibles via un store (App store pour iOS et Play Store pour Android).

Cette série de deux articles ne traite pas de la plateforme Windows Mobile 10 notamment pour sa faible part de marché (env <1%) mais aussi eut égard de l’aveu d’échec de la part de Microsoft : https://t.co/0CH9TZdIFu https://t.co/ePsySxR3LB

Le développement multi-plateforme

Afin de ne pas réinventer la roue lors de la création d’une application (mobile ou non) lorsqu’on cible plusieurs plateformes il peut être intéressant de passer par un développement multi-plateformes (ou cross-platform). Ce type de développement à l’avantage de factoriser la logique métier et d’abstraire les spécificités de développements propres à chaque plateforme en utilisant un framework (ensemble d’outils pour la création de logiciels). La simplicité gagnée par cette abstraction que propose le framework utilisé pourra conduire dans certains cas au développement de modules spécifiques destinés à combler les lacunes du framework.

Les différentes manières de faire un développement multi-plateforme

1. Full web

La solution la plus simple consiste en la réalisation d’un site web. Toutes les plateformes mobiles disposent d’un navigateur web ainsi il est tout-à-fait possible de créer une application interactive avec les technologies standards du web (HTML/JS/CSS). C’est ainsi que fonctionnent nos produits Cities et Dashboard. Cette solution facilitant le développement présente le désavantage de ne pas pouvoir tirer entièrement partie du support mobile et de certains de ses capteurs : tels que le gyroscope. De plus en passant par un navigateur web le développement hérite de tous les problèmes du développement web : compatibilité sur tous les navigateurs, performances limitées.

 

2. Applications Hybrides

Les applications hybrides sont des applications web développées avec les technologies standards du web mais encapsulées dans une application via une WebView. Cette solution est similaire à la création d’un site web, les problèmes restent les mêmes vu que ces frameworks utilisent les Webview du système sur lequel ils sont déployés. Néanmoins via ces technologies il est possible de développer des modules spécifiques pour proposer des fonctionnalités propres à chaque système.

Parmi les frameworks existants on peut citer : Apache Cordova et Ionic (qui se base sur Apache Cordova)

 

3. Frameworks dédiés au développement multi-plateformes

Cette solution consiste à developper de véritables applications natives via un framework qui va abstraire les spécificités propres à chaque plateforme pour proposer des interfaces logicielles de plus haut niveau. Cette solution présente l’avantage d’abstraire les problématiques de développements propres à chaque plateforme en les réduisant au développement de modules spécifiques.

La solution offrant le plus de liberté pour une développement reste l’utilisation de ce type de framework que ce soit pour les performances ou encore la création de modules spécifiques. Cette liberté se paye par l’utilisation d’outils parfois complexes et la familiarisation avec des frameworks offrant de nombreuses fonctionnalités.

 

 

 

 

Présentation de quelques frameworks dédiés au développement multi-plateformes

Parmi les frameworks dédiés nous allons nous concentrer sur les trois frameworks qui suivent : Unity, Xamarin et React-Native. Nous avons ciblé ces trois framework pour leurs communautés existantes ou grandissantes, leurs supports, leurs utilisations et leurs complexités d’utilisations.

Nous n’aborderons pas les frameworks comme : Qt ou encore Juce qui pourraient aussi répondre au besoin.

1. Unity

Ce framework est principalement dédié à la conception de jeu vidéo, néanmoins il permet de créer des applications multi-plateformes aussi bien mobiles que bureautiques. L’utilisation d’Unity devient vite limitée lorsqu’il est question de créer une application qui n’est pas un jeu, l’IDE étant centré sur des concepts de « scene » et « assets » propres au Jeu vidéo.

2. React-Native

Ce framework, récemment propulsé par Facebook, propose d’utiliser la simplicité d’utilisation de la technologie React pour créer de véritables applications natives. Ainsi en utilisant ES6 et JSX la création se veut simplifiée et permet de profiter des performances et composants des systèmes mobiles. Côtés points faibles, React-Native reste une technologie relativement nouvelle et dispose d’une communauté encore grandissante, d’autre part React-Native hérite de la license propre à Facebook qui spécifie qu’on ne doit pas utiliser cette technologie dans des produits concurrents de Facebook ou assimilés « The license granted hereunder will terminate, automatically and without notice, if you … take a direct financial interest in, any Patent Assertion: (i) against Facebook or any of its subsidiaries or corporate affiliates ». (https://github.com/facebook/react-native/).

3. Xamarin Forms

Désormais racheté par Microsoft, Xamarin grand acteur de l’univers .NET sur plateforme Mono (VM .Net open source) propose la solution Xamarin Forms pour créer des applications Android/iOS/UWP. Pleinement intégré à Visual Studio (Windows ou Mac), Xamarin Forms offre une solution logicielle complète pour créer des applications. Son modèle économique reste le principal frein à son utilisation (voir le pricing Visual Studio).

Dans le prochain article…

La suite de cette article (à paraitre très prochainement) proposera un retour d’expérience via une mise en oeuvre concrète des trois frameworks dédiés au développement multi-plateformes. Le cas présenté sera appliqué à une problématique qu’on peut rencontrer lorsqu’on souhaite proposer une application mobile.

 

Article rédigé par Marc-Alexandre Blanchard.