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 :

Kotlin-Native Target Platforms

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 :

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

Generate .frameworks

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

Frameworks location

This framework has to be imported in your XCode Project :

Import Framework

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.

How Kotlin types as bounds

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 :

Content of the common module
Common module hierarchy

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 :

Interface Settings — Common

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 :

Implementation of Settings — iOS

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 :

Dependency Manager — iOS
DependencyManager — Android

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 :

XCode controller

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 !