[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]
