Kotlin multiplatform - Le code commun

Edouard Ouvrard

Publié le 19 janvier 2024 - 3 min de lecture

cover

Kotlin multiplatform est un framework qui permet aux développeurs d’écrire du code qui peut être compilé pour plusieurs plateformes, telles qu’Android, iOS, macOS, Windows, Linux et JavaScript. Cela signifie que vous pouvez écrire votre code une seule fois et le déployer sur toutes ces plateformes, ce qui peut vous faire gagner un temps et des coûts de développement. Vous pouvez ainsi mettre en commun des parties importantes de comportement métiers et éviter les écarts entre les plateformes.

Quelles parties du code en commun ?

Dans une application multiplateforme, nous pouvons imaginer que tout le code métier, les accès aux données (API/Cache local/…) devraient être mis en commun.

Il y a très peu de valeur ajoutée à dupliquer ce code sur toutes les plateformes puisque l’on en attend exactement le même comportement.

L’avantage de Kotlin Multiplatform contrairement aux autres frameworks, c’est que l’on reste libre pour partager (ou non) la partie visible pour les utilisateurs, les interfaces.

Une fois notre librairie commune compilée, nous pouvons l’importer dans un projet et continuer d’utiliser les SDK fournis par les plateformes pour concevoir des interfaces performantes, et qui respectent les standards.

shape vMq2DarLp8389oAkYz0NI

La liberté de choisir

Comme nous pouvons le voir dans ce schéma, le framework ne nous impose rien, nous sommes maîtres de ce que l’on partage.

La dernière partie partageable reste les interfaces, rendu possible avec le développement de Compose Multiplatform, un framework complémentaire à Jetpack Compose pour Android, encore en alpha, cela reste quand même intéressant à regarder pour partager des composants d’interface très spécifiques et devant être au pixel près identique sur chaque plateforme.

1MhUDiK q4FTzl image

Du code commun spécifique

Pour écrire du code commun en Kotlin multiplatform, vous pouvez utiliser des interfaces ainsi que les directives expect et actual.

Exemple

//Code commun
interface Platform {
val name: String
}
expect fun getPlatform(): Platform
class Greeting {
private val platform = getPlatform()
fun greet(): String {
return "Hello, ${platform.name}!"
}
}
//iOS
import platform.UIKit.UIDevice
class IOSPlatform: Platform {
override val name: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}
actual fun getPlatform(): Platform = IOSPlatform()
//Android
import android.os.Build
class AndroidPlatform : Platform {
override val name: String = "Android ${Build.VERSION.SDK_INT}"
}
actual fun getPlatform(): Platform = AndroidPlatform()

Dans cet exemple, la partie commune du code fournie une interface et attend que son implémentation soit faite pour chacune des plateformes via la fonction getPlatform().

Nous pouvons ensuite voir que chacune d’elles est implémentée pour iOS et Android.

Puis la classe Greeting, elle aussi dans le code commun, pourra ensuite être utilisée et utilisera de façon transparente les implémentations de chacune des plateformes.

Les dépendances iOS pour l’exemple

Les dépendances du SDK Apple (telles que Foundation ou Core Bluetooth) sont disponibles sous forme de bibliothèques pré-construites dans les projets Kotlin Multiplatform. Elles ne nécessitent aucune configuration supplémentaire.

Voici un extrait de la documentation de Kotlin multiplatform qui nous indique que nous pouvons, dans la partie iOS Kotlin, importer si besoin les dépendances Apple.

import platform.CoreBluetooth.*

Le futur

2w1gTDmUFlT7q6 image

La target WASM (WebAssembly) de Kotlin multiplatform est une fonctionnalité intéressante qui ouvre de nouvelles possibilités pour la portabilité du code entre les différentes plateformes. WASM est un format de code portable qui peut être exécuté dans un navigateur web ou sur un serveur, ce qui signifie que vous pouvez écrire du code Kotlin qui peut être déployé sur n’importe quelle plateforme prenant en charge WASM.

Exemple d’utilisation

Prenons par exemple du code qui doit générer des lignes de logs à partir d’un objet connecté. Ce code sera généralement écrit en C ou C++ directement dans l’objet. Nous pouvons également imaginer que l’objet possède du code pour lire et décoder ces lignes de logs.

Plus tard dans la vie de l’objet, ces logs sont récupérés en Bluetooth via une application Android ou iOS, puis envoyés au serveur pour être stockés en base de données.

Dans cet exemple très simple, aucune des plateformes n’a encore eu besoin de décoder ces logs. Avec une base de projet écrite en Kotlin multiplateforme, nous pouvons écrire ce code et le partager. Avec WASM, nous pourrions encore aller plus loin en partageant directement le binaire sur l’objet pour qu’il puisse produire ses logs, mais aussi sur un backoffice WEB afin de les décoder pour afficher la traduction à l’utilisateur.

Le plus grand avantage par rapport à la compilation d’une librairie C/C++ via Kotlin multiplateforme est la possibilité de remplacer le comportement de ce binaire WASM et de le mettre à jour via Bluetooth, par exemple, sans avoir à mettre à jour le firmware de l’objet.

FUXw7EJEyqGHFV image

Prêt pour la production

Kotlin Multiplatform est passé en version stable en novembre 2023 et respecte désormais certaines règles de rétrocompatibilité que s’impose JetBrains.

Nos retours d’expériences montrent que c’est une très bonne technologie qui permet de réellement gagner du temps sans compromettre la qualité de l’expérience utilisateur, sans perdre de temps sur les mises à jour des systèmes d’exploitation.

Le meilleur des mondes 😉

Si vous avez des projets à déployer sur plusieurs plateformes, n’hésitez pas à nous contacter.