KMM ou Kotlin Multi Platform Mobile

Introduction

Kotlin Multi Platform Mobile est un SDK permettant un développement d’application mobile multiplateforme en Kotlin. Il offre la possibilité d’avoir du code partagé entre une application iOS et une application Android.

Le développement d’une seule code base permet :

  • Une maintenabilité accrue
  • Un développement unique de modules communs
  • Une interopérabilité avec Java
  • Une réduction de temps de développement -> Un coût moindre

Vu comme ça c’est super, à la fois côté client, qui a un produit stable moins couteux, mais aussi d’un point de vue technique, et c’est pourquoi il est de plus en plus utilisé.

D’un point de vue un peu plus technique KMM c’est quoi ?

Avant d’aller plus loin et de vous parler plus en détails de notre expérience projets avec KMM, commençons par les quelques aspects techniques de ce SDK.

Un langage de programmation : Kotlin

Sorti du ventre de JetBrains en 2010, il avait pour but d’être l’alternative plus stable et beaucoup moins verbeuse du Java qui connaissait déjà trop de limitations. Kotlin se devait d’être totalement compatible avec Java pour faciliter la migration des nombreux projets existants en Java vers ce dernier. JetBrains à qui l’on doit aussi IntelliJ un IDE à part entière mais aussi et surtout, concernant le développement mobile, la base d’Android Studio. C’est pourquoi on retrouve également la possibilité sous Android Studio d’avoir un module facilitant le développement KMM. Ce langage typé connait un franc succès et grâce à KMM cette communauté qui rassemble iOS et Android grandit de jour en jour.

Du multiplateforme

Dans la plupart des applications classiques, de nombreuses fonctionnalités sont dupliquées sur chaque plateforme telles que les modules d’authentification, de récupération de la donnée et du traitement de celle-ci avant d’être envoyée dans les vues. Avec KMM, ce code est partagé et n’a donc pas besoin d’être développé deux fois sur deux langages différents.

A priori concernant les solutions de multiplateforme mobile

Limitations de l’utilisation des modules natives iOS et Android

Même si beaucoup de choses peuvent être réalisées dans la partie partagée sous Kotlin, il peut arriver de ne pas pouvoir tout faire en un seul code. Pour ce cas-ci ou dans l’éventualité où on préfèrera utiliser des fonctions natives, KMM a également prévu le coup avec le pattern protocolaire expect/actual.

Le compilateur s’assure que toutes les déclarations préfixées de « expect » ont la déclaration correspondante préfixée de « actual » dans les modules iOS et Android. Cela peut être utile lorsqu’on a besoin de fonctionnalités telles que la récupération des informations d’un device qui est propre à chaque plateforme par exemple.

Performances

Coté perfs, on pourra aussi noter qu’elles sont les mêmes que pour du natif car … c’est du natif ! Le code partagé est compilé en bytecode java pour Android et en binaire natif pour iOS. Via une seule et même codebase on se retrouvera avec un SDK natif à chaque plateforme.

Natif donc utilisable comme n’importe quel SDK standard avec un socle natif, que ce soit Java/Kotlin pour Android, ou objectif-C, Swift et SwiftUI pour iOS. On peut alors facilement avoir toute la logique métier d’une application dans ce SDK et ne traiter uniquement ce qui est de l’ordre de l’UI séparément.

Intégration de bibliothèques externes

Entre la partie shared et la partie Android, du classique, un import dans les fichiers de configuration Gradle comme ci-dessous et le tour est joué :

Pour iOS, ce n’est que très légèrement plus compliqué car c’est aussi au sein des fichiers de configuration de la partie shared que ça se passe. Il suffit de déclarer dans notre configuration si l’on souhaite utiliser cocoapods, swift package manager, ou directement déclarer le path vers une librairie locale.Exemple avec cocoapod :

Un exemple concret :

Dans le cas où nous voulions récupérer les actualités de Mobiapps, y compris cet article, nous pouvons avoir ce type d’implémentation :

Exemple avec Android / Jetpack Compose et iOS / SwiftUI et une base GraphQL et son module de communication Apollo

Dans la partie « shared » de KMM, nous avons un dépôt permettant la récupération des actus de Mobiapps :

Pour la partie Android, nous instancions le dépôt dans l’activity voulue, puis nous déclarons une variable observante de la valeur de la liste de news du dépôt, laquelle sera utilisée dans la construction de nos vues. Comme ci-dessous :

Pour la partie iOS, j’opte pour du MVVM avec SwiftUI, on se retrouve donc avec un viewModel ayant un dépôt de news et une fonction asynchrone.

Cette fonction aura pour but de lancer l’observation des changements de la liste de news liée à ce dépôt.

Pour ce qui est de la vue, nous avons juste à observer les changements liés au viewModel et à itérer sur nos résultats pour les afficher dans notre vue.

Une fois la librairie partagée contenant le dépôt de news importée, libre à vous d’avoir des applications natives codées de façon similaire classique ou de vous essayer aux nouveautés telles que Jetpack Compose ou SwiftUI.

Notre expérience KMM

D’après notre expérience sur des projets utilisant KMM, beaucoup de similitudes ressortent quant au forces et faiblesses de cette solution.

Les plus :

  • Langage identique pour la partie Android et la partie shared
  • IDE adaptée au langage Kotlin et au plugin KMM
  • Courbe d’apprentissage rapide
  • Code moderne et élégant se rapprochant du Swift
  • Intégration de bibliothèque externe
  • Mises à jour régulières
  • Communauté active et documentation riche
  • Compilation rapide

Les moins :

  • Certains types mal configurés tels que les booléens qui auront besoin d’un parseur spécial pour iOS
  • Être vigilant sur fonctions asynchrones qui peuvent être un gouffre mémoire lors de multiples appels à des WebServices sans annulation de la requête précédente
  • Mise en place de l’architecture plutôt compliquée si peu amateur de Gradle

Conclusion

D’abord réticent à retenter l’expérience de passer de solutions natives vers du multiplateforme après une expérience mitigée sur Flutter, j’ai eu l’occasion de travailler avec KMM. Grâce à la flexibilité d’intégration de KMP, nous pouvons extraire la totalité des règles métier dans le code partagé. Les modules de règles métier sont dans la plupart des cas dupliqués car indépendants de la plateforme utilisée. La plupart des évolutions ou features sont rapide à mettre en place, le Pair-Programming sur la partie shared pour ensuite se séparer pour chacun développer son UI de manière autonome se révèle être un très bon compromis entre rapidité et stabilité. C’est sans aucun doute une solution que nous verrons de plus en plus dans le développement mobile et c’est avec grand plaisir que Mobiapps veillera à vous accompagner dans vos projets KMM.

Vous souhaitez en savoir plus ? Contactez nous !

Bastien LEBRUN – Développeur iOS