7. Why share code?
• DRY
• same code/logic for different platforms
• productivity, features, less bugs, more platforms
8. Why share code?
• crossplatform in the past
• networking library in C
• Windows Mobile
• Windows
• Android
• Linux
9. Why share code?
• sharing entire components
• JVM servers can share business logic with Android apps
• All client apps share similar logic and features
12. Why NOT share code?
• Performance
• Slower innovation
• shared UI
• All or nothing
• Vendor lock-in
• Future
• Bugs/lack of features
13. Why use Kotlin Multiplatform?
• modern, industrial language
• similar to swift, easy for java devs to learn
• great tooling, ecosystem and community
• open-source
• write once, run native everywhere
14. Why use Kotlin Multiplatform?
• doesn’t limit you to subset of all platforms
• native access to entire platform API from Kotlin
• each platform get native, optimized binary
• fix bug once, for all platforms
• interoperability
• optional sharing
16. Why not other solutions?
• Flutter, React Native, Xamarin
• not same usecase
• sharing UI - risky
• new language, new tools, new libs
• accessing platform APIs is hard, bridges
• frameworks
17.
18. Why not other solutions?
“Anything that requires you to make large decisions and
potentially large rewrites, perform large retrainings and
rehirings, or anything that has to share UI or doesn’t work well
with a native platform is, well, very risky.” - Kevin Galligan,
Touchlab
35. Kotlin/Native
• iOS, Linux, Windows, MacOS, WebAssembly...
• build full apps or libs
• access to native platform APIs
• interoperable with C/ObjC(/Swift)
• Kotlin can call C/ObjC/Swift and vice-versa
• Kotlin can extend ObjC/Swift classes and vice-versa
36. Concurrency is hard
• languages/runtimes allow unsafe concurrency
• tools - locks & volatile
• no warnings
• deadlocks
• entire burden on devs
• no guaranties of safety
• bugs leak into production
37. Saner concurrency
• new, stricter memory model
• ARC with cycle collector
• 2 simple rules
• Immutable state can be shared among threads
• Mutable data belongs to one thread
• compiler and runtime check the rules
• thread-safe code
38. Saner concurrency
+GC per thread, no suspends
+shared reference counter with swift
-no global mutable state
-new concepts, patterns, practices
-coroutines
39. Saner concurrency
• Any.freeze()
• passing mutable data by detaching
• No manual concurrency management
• Workers
• Atomics - AtomicRef/Int/Long/...
• “Stranger threads” (link in resources)
40. Saner concurrency
• work in progress
• multithreaded coroutines
• similar rules for JVM
• relaxed memory model
41.
42. Status
• beta but relatively stable
• low-risk
• production
• large projects - wait for release
• smaller projects - maybe
• part of a project - yesterday
What is Kotlin mutliplatform?
One of the goals for Kotlin is being able to compile to and run on all platforms.
3 compiler backends - Kotlin/JVM, Kotlin/JS, Kotlin/Native -
This, together with tools that facilitate efficient code sharing and projects targeting multiple platforms - KMP
We'll talk more about multiplatform, but first - WHY
DRY principle, avoid code duplication
no need to write same code/logic for different platforms
better productivity, more features, less bugs, reach more platforms
Crossplatform in native world
IKEv2 lib - windows & windows mobile, android, Linux
With rise of VMs and new languages, no common code could serve all platforms
Given proper architecture, sharing entire components can be relatively easy
JVM servers can share business logic with Android apps
All client apps share similar logic and features
Spotify client apps -
while frontend/UI differs from platform to platform
features and logic behind are mostly identical
it's easy to see how sharing code across platforms can be really benefitial for various usecases
Mobile platforms share a lot in common
Android & IOS apps tend to look similar, share identical features, same usacases,
platforms have same capabilities and similar limitation
app arhitectures are very similar
if youre using some layered arhitecture like Clean arhitecure, your app might look like this
Domain layer (business logic) is usually great candidate for sharing as it doesn't depend on frameworks and platform
Data layer - works with identical data across platforms
performance tend to suffer,VM, interpreters, script languages
inovation slows down as advancements on one platform cant be used in shared solutions
UI is limited to shared features, not as good as native
enitire app must be written in given framework
changing framework requires entire app rewrite
will that framework even exist in 5-10 years?
if we run into an issue or framework lacks needed feature, project goes back to starting point
modern, industrial language
similar to swift, easy for java devs to learn
top tooling, great ecosystem and community
write once, run native everywhere
doesn’t limit you to subset of all platforms
native access to entire platform API from Kotlin
each platform get native, optimized binary
fix bug once, for all platforms
interoperability
pick what you want to share,
no need to decide on porting entire app
pick easily shareable compoment, give it a try
even if you don't want to continue using it, you have perfectly fine Android code
low risk
easy to adopt - easy to convince management - they care about risk
sharing UI - risky - doesn't feel like native
Flutter/ReactNative
App using Flutter is Flutter app, app using RN is RN app, app using KMP is just an app - you can add KMP library/module without affecting app structure/framework. You can add two, three. You can add KMP lib to Flutter or RN app.
- new language, new tools, new libs
- issues are localized in KMP
- framework vs library
optional sharing - pick your adventure
who's using or supporting KMP
coroutines - great asynchronous programing
ktor - Ktor is a framework for building asynchronous servers and clients
you can build web servers with it and it also offers multiplatform network client you can use in your applications
with ktor, you can write all your networking code once in common code and use that on all platforms
serialization - offers reflection-less serialization of kotlin classes to JSON and binary formats
uses a compiler plugin to generate code needed for serialization
supports all platform - common code
SQLDelight - DB library. SQLDelight generates typesafe APIs from your SQL statements. It compile-time verifies your schema, statements, and migrations and provides IDE features like autocomplete and refactoring which make writing and maintaining SQL simple.
Multiplatform library, write all your DB code once in common code and use on all platforms
okio - modern I/O library, okhttp
okhttp - esential HTTP library for andoird devs, some people may know it as retrofit, which builds upon it. Rewriten in Kotlin, we might get multiplatform release in the future
Touchlab - active in K/N developement, stately - concurrency in K/N,
IDEA community edition - free
Ultimate edition
new project templates
KMP templates - clone/fork from github
write build script yourself
target - target is a part of the build that is responsible for building, testing, and packaging a complete piece of software for one of the platforms
current state of dependencies
what if we wanted to add a server to the picture?
we can improve -
Android & iOS are both clients are we'll probably need some client-specific code that we wont need on server - clients sourceSet
Android & server both run on JVM - maybe we can put some common dependencies and utilities in jvm sourceSet
we added jvm target, with “server”sourceSet
-> concurrency
Traditionally languages allow (and promote) inherently unsafe concurrency
Straighforward code is thread-unsafe by default
Languages/runtime offer tools for handling concurrency
However these tools haven't changed much since time of C - volatile & locks (synchronized)
Languages do nothing to prevent or warn about issues, they are hard to detect
Developers must find potential issues and implement safety themselves using given tools
Overuse of misuse of concurrency tools lead to deadlocks
Entire burden on devs
There is no practically no guaranties of thread-safe code, testing just can’t reproduce some concurrency bugs and debugging doesn't help much
Often these bugs leak into production
In order to address this issue, Kotlin creators indroduced Saner concurrency
Automatic Reference Counting
freeze converts mutable state into immutable state,
also all it's references, recursively
Data can be manually detached from thread and passed to another one (memory leak)
there's no synchronized/volatile, there's no need for them
workers are threads that can execute tasks, execution returns future with task result
atomic - way to bypass restrictions of memory model - they can be shared across threads although they hold mutable data