KMM : zoom sur Kotlin multiplatform

On vous en dit plus sur le nouveau projet de JetBrains, Kotlin Multiplatform Mobile.
Clément BROSSETTEMis à jour le 23 Sept 2022
KMM kotlin multipaform mobile

Nous sommes dans une période où les applications mobiles sont omniprésentes.

Depuis un certain temps, nous avons vu des technologies multi-plateformes arriver sur le marché. Ces dernières ont démocratisé le développement mobile par une réduction des coûts et des temps de développement. Le principe étant de mutualiser son code et de pouvoir produire une application pour chaque environnement depuis un unique projet.

Mais ces technologies ont des limites. Elles ne seront jamais aussi performantes que des applications dites natives codées avec les langages préconisés par Apple ou Google.

De plus, elles posent souvent un problème de fiabilité et de maintenance. Cela représente souvent un coût sur le plus long terme que l’entreprise ne voit pas comparé au coût de développement de base avantageux.

On ne le répétera jamais assez : la maintenance et le maintien dans le temps d'une application représentent les plus grosses dépenses pour une application.

Autant de problématiques que JetBrains essaye de balayer avec son nouveau projet KMM.

Kotlin Multiplatform Mobile : c'est quoi ?

Tout d’abord Kotlin n’est plus à présenter. C'est un langage qui s’est imposé chez Google comme le langage préféré des développeurs pour le développement d’applications natives AndroidAndroid est un système d'exploitation mobile basé sur Linux..

Mis à disposition par l’éditeur JetBrains, KotlinLangage de programmation permettant de développement des applications mobiles Android natives. est un langage orienté objet à typage statique qui permet entre autres de compiler pour la machine virtuelle JavaLangage de développement très populaire ! et donc Android. Son gros point fort est également l’interopérabilité avec les autres langages autorisés par Google (Java, C++).

Kotlin Multiplatform Mobile (KMM) est un kit de développement basé sur le langage Kotlin permettant de développer des applications iOS et Android.

Un projet actuellement en alpha. Une bêta est prévue pour cet automne 2022. Malgré ça, il est déjà fiable pour des mises en production, plusieurs grosses entreprises lui font confiance et l’utilisent comme Philips, Netflix, Leroy Merlin ou VMWare.

Kotlin Multiplatform Mobile : du code partagé entre iOS et Android

En effet, c'est son principal intérêt.
Il s'agit de gagner en temps et réduire les coûts en partageant un maximum de code. Ce code pourra très bien être réutilisé dans d'autres nouveaux projets, et même dans des applications natives classiques déjà existantes tout en gardant la robustesse, la simplicité de maintenance et d'évolutions des versions ainsi que la performance que l'on reconnaît au natif.

Tout ce code partagé est compilé de plusieurs manières pour arriver à ce résultat.

Pour Android, le code Kotlin est compilé en bytecode JVM avec Kotlin/JVM.
Pour iOSSystème d'exploitation des appareils Apple. en revanche, c'est le binaire natif qui est visé avec Kotlin/native. Cette fonctionnalité permet de compiler pour des plateformes où l'exécution d'une machine virtuelle comme la JVM n'est pas souhaitable ou possible : par exemple iOS.

Kotlin Multiplatform Mobile : comment ça fonctionne ? 
kotlin multiplateform kmm

Un projet se découpe en plusieurs sous parties, dans notre cas trois parties :

  • androidApp: code source de l'application Android
  • iosApp: code source de l'application iOS
  • shared: le code partagé entre les deux plateformes

Dans notre exemple, nous devons appeler la méthode du code partagé depuis notre partie native iOS et Android.

 struct ContentView: View {
            let message = MyClass().sayHello()
            var body: some View {
                Text(message)
            }
        }
        struct ContentView_Previews: PreviewProvider {
            static var previews: some View {
                ContentView()
            }
        }
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent(R.layout.activity_main)

    binding = DataBindingUtils.setContentView(this, R.layout.activity_main)
    binding.textView.text = MyClass().sayHello()
}

Les projets androidApp et iosApp peuvent être ouverts respectivement sur Android Studio et Xcode. C'est à cet endroit que sera implémentée l'interface utilisateur spécifique à chaque plateforme.
Les deux projets possèdent une dépendance vers le module shared qui leur donne accès au code métier partagé.
Grâce à cela vous pouvez appeler n'importe quelle fonction ou classe provenant du module shared depuis votre Activity ou ContentView.

Le dossier shared est également divisé en trois parties :

  • androidMain: contient le code spécifique à Android
  • iosMain: contient le code spécifique à iOS
  • commonMain: contenant le code partagé

Le principe de base est simple.
Tout le code partagé se rédige dans le commonMain.
Les deux autres parties servent à écrire du code spécifique pour sa plateforme. Ce code pourra être injecté dans le commonMain.
Ainsi, on se retrouve avec la possibilité de variabiliser notre partie commune et de pouvoir injecter des informations différentes selon la plateforme dans une fonction.

Nous pouvons donc déclarer notre classe dans la partie commonMain qui est utilisée par nos deux projets natifs.

class MyClass {
    fun sayHello(): String {
        return "Hello, ${Platform().platform}!"
    }
}

Nous utilisons ici une autre classe, Platform qui va nous permettre de variabiliser notre code partagé.

Mais concrètement comment ça fonctionne ?

On utilise le mécanisme de expect/actual. Avec expect dans notre commonMain nous pouvons spécifier qu'une classe ou une valeur est attendue. Il faut ensuite la déclarer dans androidMain et iosMain avec le mot clé actual avec l'implémentation qui vous convient.

Dans notre exemple, il nous faut donc déclarer une classe Platform avec le mot-clé expect :

expect class Platform() {
    val platform: String
}

Nous pouvons donc maintenant écrire les différentes implémentations de cette classe dans les codes spécifiques de chaque plateforme.

actual class Platform actual constructor() {
    actual val platform: String = "IOS"
}
actual class Platform actual constructor() {
    actual val platform: String = "Android"
}

Il faut comprendre que ce mécanisme permet de partager à peu près ce que l'on veut.
On peut donc centraliser dans une seule base de code des éléments comme une base de données, un service ou encore un client http qui pourront obtenir leur configuration via les expect/actual.

KMM ou cross-plateform

Une philosophie différente

Un projet KMM se présente différemment d'un projet d'application multi-plateforme classique. Ici, le but n'est clairement pas d'avoir une application unique, mais de pouvoir mutualiser un maximum de code entre plusieurs implémentations spécifique si besoin.

C'est une nouvelle vision du cross-plateform qui nous est proposée par JetBrains.

Cela permet plusieurs choses, notamment proposer une implémentation graphique spécifique, une UIL'UI signifie "user interface", et se compose de tous les éléments graphique d'une interface utilisateur./UXL'UX signifie "user experience" et définit l'ensemble des éléments permettant l'utilisation du site web de façon optimale. différente pour chaque plateforme (web / IOS / Android).

Cela peut être un avantage important dans un monde où les géants Google et Apple se veulent de plus en plus exigeants sur la qualité des applications publiées et émettent des guidelines différentes.

L'utilisation de l'écosystème de chaque plateforme est également possible, comme des jetpack-compose ou SwiftLangage de programmation créé par Apple, pour le développement sur leur différents périphériques.-ui pour garder l'exemple de l'interface utilisateur.

Le panel de plateformes disponibles est également plus large. Les classiques navigateur, mobile et web. mais également smartwatch et tout ce qui embarque Android.

Nous pouvons également toucher des plateformes où la JVM n'est pas forcément présente comme des applications sur Windows, Linux, MacOS, WatchOS.

Ces avantages, une fois combinés, nous permettent de répondre à des besoins hors d'atteinte d'applications multi-plateformes classiques comme des expériences utilisateur différentes pour des appareils différent, mais avec la même logique métier derrière.

C'est un point important avec l'évolution des objets connectés de plus en plus présents autour de nous comme des TV ou des montres. 

KMM kotlin multipaform mobile

Kotlin Multiplaform Mobile : quelle performance ?

Un autre intérêt de KMM est d'être basé sur du Kotlin, un langage reconnu basé sur Java qui nous donne la possibilité de compiler en bytecode Java pour Android ou en binaire natif pour iOS. Cela permet d'être comparable aux applications natives.

Zoom sur les projets existants

Si vous possédez déjà des applications mobiles, il est possible de développer vos nouvelles fonctionnalités en KMM. Il vous suffira d'incorporer sous forme de dépendance dans vos projets iOS ou Android.

De plus, si vous possédez déjà des applications Android, KMM vous permet de les rendre compatible iOS.

Vous trouverez des guides détaillées sur la documentation officielle.

Pour conclure

Kotlin Multiplatform est une solution très prometteuse bien qu'elle soit encore en développement.

KMM est une solution performante qui prend une autre direction de ce que l'on connaît déjà et qui lui permet de gommer les défauts connus tels que la performance, l'opacité des surcouche JavaScriptLangage de scripting orienté objet et des interfaces utilisateur qui n'ont pas un feeling natif.

Il faut garder en tête que Kotlin Multi-plateform est toujours en Alpha, ce qui explique que certaines fonctionnalités ne sont pas encore complètement disponibles. Nous attendons donc la Bêta afin de voir l'évolution de ce qui nous est proposé.

En résumé, KMM est une nouvelle vision qui lie le meilleur des deux mondes et une promesse très alléchante autant pour les développeurs que pour les clients. Affaire à suivre !