[MUSIC PLAYING]
WOJTEK KALICINSKI: Hi, everyone.
My name is Wojtek.
And I wanted to share with you a short story
about my experience with the new Kotlin multi-platform project
in Kotlin 1.3.
So when we come to these conferences,
talk about Android, talk about running Kotlin on Android
for making Android apps, what we really mean is Kotlin JVM.
That's the Kotlin that we know that gets
compiled to Java bytecode.
And then we can transform it into .dex files,
run it on Android.
But it can also run on cloud servers, on our desktops,
and so on.
Now there are two more flavors of Kotlin actually,
or compilation targets.
First one, Kotlin JS, for running
JavaScript in a web browser environment
or even something like cloud functions or Node.js.
And then there's Kotlin native, which compiles down
to machine code in native libraries
that can run or target various platforms,
such as IOS, desktop apps, even WebAssembly, and even Android.
So how do we actually get started with this?
So Kotlin 1.3 introduces a new project structure
and a new plug-in that's called Kotlin multi-platform.
And if you apply that to any of your modules,
you can then select from a set of presets
to target any of these platforms.
So here, for example, I'm targeting an Android library
and a js target.
Now when you add these to your module,
it automatically creates source sets for each of these platform
specific Kotlin files.
So if you put your Kotlin files in the js main folder,
they will get compiled or transpiled to JavaScript files.
Now what do I mean by Kotlin specific--
sorry-- platform specific Kotlin?
Now if you go and browse the documentation, the reference
pages for each of the Kotlin packages,
and you mouse over any of them, in the top right
you will see these multicolored chips
that tell you which compilation target
this library is available on?
So here, for example, the Kotlin browser package
that lets you access interfaces for document and window
from the web browser environment, probably only
makes sense on a js target.
And that's how it is.
Now fortunately, many, many of the core
libraries and functions are available across all
the compilation targets.
In fact, you can see a fourth one, Kotlin common,
which means this is a pure Kotlin
library that can run independent of any platform that's
targeting.
And in fact, if you add the multi-platform plug-in
to your project, along with the platform specific source sets,
you also get a common source set where you can
put platform independent code.
Now the thing about platform independent code is,
it cannot call any of the platform APIs.
It cannot call any of the js specific or Android specific
APIs.
The other way, of course, works.
You can have your platform specific code
from any of the flavors depend on a shared common library
or source set.
So knowing all that, I set out to write an example app just
to learn about Kotlin multi-platform.
And I decided to make a small Sudoku game.
Now one thing I have to say about Kotlin multi-platform
is, it's not a toolkit that lets you write an app once and run
it everywhere.
I still need to create an Android app
with Android specific code, just like I normally
would, and then a web page with some JavaScript code
just to initialize things, like entry
points to my app, lifecycle UI, and so on.
But then, what I do is, all my shared business logic--
so in my case, it's the Sudoku engine that
solves and generates Sudoku boards for me,
I take it out and put it in a shared
library using Kotlin common.
And in fact, the only source set I have in this library
is common main.
So I put all my code there.
And that means it's available across all the platforms
that I choose to target.
OK.
But then I thought, OK, I have this core engine
for solving my Sudoku code.
But I would also like to draw the board on the screen.
And why code it for each platform
separately if it should look the same on each of them?
So I thought, wouldn't it be nice
if I had an API for drawing on the screen that's
completely platform independent, something
that can multi-platform canvas?
But then what I want to do is I want to actually
have it delegate to each of the platforms implementations.
So I want to use the Android canvas
to draw on Android while I use the HTML
canvas to draw on a website.
The thing is, I just told you that Kotlin common code cannot
call any platform interfaces.
So I can't really depend on these
and export them from this module.
So how does it work in Kotlin?
Well, there's this expect and actual mechanism
that lets you declare expected classes in your common code,
which is something almost like defining an interface in Java.
And then in each of my platform specific source sets,
I provide the actual implementation
that can depend and use platform APIs,
such as the Android canvas.
Now, when I add that dependency from my common source
set to the other one, it looks something like this.
But actually, when compiling for a specific platform, such a js,
this dependency will actually use the correct HTML5 canvas.
[GONG]
[CHUCKLE]
OK, if I could just show the link to the project
so that everyone can look at it, that would be great.
[LAUGHTER]
Yep.
SPEAKER 1: [INAUDIBLE]
[CHUCKLE]
[APPLAUSE]
WOJTEK KALICINSKI: Yeah that's it.
[MUSIC PLAYING]