My first experience with Kotlin Native
With the recent release of Kotlin 1.3, I heard about the capability to create multi-platform mobile applications 🤔
It’s now possible to share code between my android & ios apps ??? What’s the magic behind that ?
Let me show you how I succeed to create my first Android & iOS compatible module, and how to integrate it inside real applications.
Kotlin can compile to ANYTHING !
Kotlin’s last release enforce the concept of a multi-platform language, you already can use Kotlin to produce JVM binaries and JS bundles, it’s now possible to produce Native frameworks !
By native I mean iOS code, but not only ! Following the official documentation, it’s possible ton generate code compatible with a lot of native architecture :
I will only focus here on the Kotlin-Native iOS compatibility, and demonstrate you how to generate a mobile application sharing kotlin code, compatible with Android & iPhone !
How I created my multi-platform project
Mhhmmm let me guess what would be the perfect IDE, compatible with Gradle and Android 🤔
Of course IntelliJ Idea 😁 (you can also use Android Studio)
To create my project, I forked the official Kotlin-Conf app made by JetBrain, and modified the sources !
You can also start from 0 by following the official documentation to configure a multi-plateform project
Here’s my repo :
Contribute to florent37/KotlinNativeSample development by creating an account on GitHub.github.com
Here’s the simple app I made, you write the login of a github user, and it displays his complete name, its avatar and his company. It’s not a complicated application, but it contains some Http call, a Json deserialization and can be architectured using MVP
How a multi-platform project looks like ?
This multi-platform project is made by 3 modules :
- common : contains kotlin mutualized code
- android : contains android application
- appios : contains the xcode project
You can define platform-specific implementations directly from these modules, or inside flavors of the common module : here iosMain & jvmMain
Kotlin native use Konan, which is a LLVM compiler, to generate a .framework from our common module. For Android developers : .framework are the equivalent to .jar
This framework has to be imported in your XCode Project :
Understand Kotlin Types
Kotlin has been initially created to produce JVM bytecode.
But using only Kotlin classes : Int, Double, List, Map, etc, it’s now possible to bind theses objects with the platform implementations.
You can see the current implementation watching the generated .h of your .framework, using this common class :
It will generate this kind of code inside the common.h file :
What can I put my common module ?
The response is easy : almost everything that’s not UI or platform-dependant !
I’m working on MVP on my project, I added the Presenter, its view, the repositories, the api and the models inside my common module :
Here the only platform specific layer is the API, let me explain you different ways to have diferents code depending on the platform :
Platform-specific Implementation by library
Using the same logic using in product flavors on Android : all flavors should expose the same public classes (if they’re used by our project), you can specify specifics Gradle dependencies, here for the HTTP Ktor library, used in my GithubAPI :
From my GithubApi, I can use the class HttpClient, which has a different implementation on Android & iOs
Note you can use kotlin coroutine to execute asynchronous methods in our common module !
With Ktor I used the kotlinx-serialization lib to decode json as models
Write iPhone code with Kotlin
Kotlin-Native allows you to compile generic code to a framework, binding types to the platform types, but it also allows you to write iPhone code directly in Kotlin !!!!
I’m not encouraging you to create all of your iOS classes in Kotlin, but you can write some platform-specific directly in Kotlin, let me show you one example, if I create an interface, in the common module, for a simple storage :
You can provide its iOS implementation directly in the generated .framework, just create a file into the iosMain module, and write your code in Kotlin, using ios classes :
Platform-specific Implementation by Injection
You can interface, inside your common module, for example, a PlatformLogger :
Then I created the implementations on each platform, here inside the android app module :
And inside my XCode project, I created a PlatformLoggerIOS, implementing the protocol PlatformLogger :
We can provide these PlatformLogger as dependency of the GithubRepository, directly from the constructor. I’m use to create a class named DependencyManager, doing some lazy initializations, stored inside the Application on Android, and inside the AppDelegate on iOS :
In my code I can just use the GithubPresenter !
Create the Android App
I just had to create a fragment and its layout, using my DependencyManager I can retrieve my GithubPresenter, then listen the EditText’s content to download and display the github user.
Finally, create my XCode app
Using the storyboard and a simple ViewController, I implemented the view of my GithubPresenter :
Here my GithubController implements GithubView, and retrieve the presenter by my DependencyManager
I can use my presenter to download the github user from my TextField’s content, then display it easily
My opinion about Kotlin-Native
It’s amazing what you can imagine for the futur of kotlin-native !
Imagine when all libraries we use will have their implementation in core/jvm/ios, we can write all our architecture code inside this framework, and only develop the UI on each platform !
Today, it’s not very easy to create a multi-platform application, the auto-completion of intelliJ is hazardous, you have some random issues while compiling your code, you cannot attach easily a debugger inside your mutualized code. Some kotlin code don’t have their equivalent in swift, for example I did not succeed to create a companion objet for my logger (I tried to reproduce a concept like Timber from Jake Wharton)
But do not forget that’s a very young technology ! It was not possible few month ago !
I’m impatient to learn more about Kotlin-Native, and create some fresh libraries compatible with Android and iPhone 😎
I give you again the code of my android/ios application, don’t hesitate to send me some comments !