If you want to share the code between Android and iOS but you don't feel like doing C++/JNI, React Native, Flutter, you must try Kotlin/Native! In this presentation we will see how Kotlin/Native is different and in some aspects superior, and how easy it becomes to develop, debug and maintain a common codebase with JetBrains tools and without sacrificing runtime performance.
3. The Plan
• Why multiplatform
• Question of the day !
• What we have in common
• Typical mobile app structure
• Existing multi/crossplatform solutions
• Kotlin/Native Multiplatform
• K/N vs K/MPP. artifacts
• expect-actual. objc/swift interop
• How do I implement…
• Multithreading
• iOS specifics
• How K/MPP is different
• Main issues "
• Conclusion
4. Why multiplatform
✅ Save costs on engineering
✅ Reduce release cycle
✅ Increase quality (less code → fewer bugs)
…
$ Poor runtime performance
% Crossplatform (== painful) debugging
& Harder to recruit and retain developers
…
5. Why multiplatform
⍰ Why try Kotlin/MPP ?
If Kotlin team creates a programming system
which allows sharing code on Android and iOS
and will be convenient to use
it mostly probably is worth trying out
And because it's fun! '
6. Question of the day
A lot of information, some things had to be left out
Ask further questions during networking session
Will it fly? !
⚠
7. Data model
Networking Persistence
Unit and
integr.
tests
UI UI tests
Serialization
Use cases
Utilities
MVx
(P, VM, I, U)
Wiring up
(DI, SL)
Share the whole app
one language
platform specific code
+
Data model
Networking Persistence
Unit and
integr.
tests
UI UI tests
Serialization
Use cases
Utilities
MVx
(P, VM, I, U)
Wiring up
(DI, SL)
Share business logicvs
+
native UI
platform specific code
+
Typical mobile app structure
8. Share the whole app
Data model
Networking Persistence
Unit and
integr.
tests
UI UI tests
Serialization
Use cases
Utilities
MVx
(P, VM, I, U)
Wiring up
(DI, SL)
one language
platform specific code
+
Share business logicvs
Data model
Networking Persistence
Unit and
integr.
tests
UI UI tests
Serialization
Use cases
Utilities
MVx
(P, VM, I, U)
Wiring up
(DI, SL)
+
native UI
platform specific code
+
Typical mobile app structure
9. Kotlin/MPP
is not a single framework but a programming system
which includes
• kotlin as a language
• kotlin-multiplatform & kotlin-native gradle plugins
• kotlin-native compiler & runtime (aka konan)
• package management based on maven
• multiplatform stdlib (kotlinx) and 3rd party libraries
10. Kotlin/MPP
helps create a layer of shared business logic*
and seamlessly integrate it with platform
specific code and native UI on each platform.
It deliberately does not aim for common UI or
WORA (write once run anywhere)
* here business logic just means code that is not UI related, e.g. connectivity,
persistence, data handling etc.
21. // common
expect fun writeLogMessage(tag: String, message: String)
// android
actual fun writeLogMessage(tag: String, message: String) {
Log.d(tag, message)
}
// ios
actual fun writeLogMessage(tag: String, message: String) {
print(tag + " : " + message)
}
Kotlin/MPP
expect - actual
22. // common
expect fun writeLogMessage(tag: String, message: String)
// android
actual fun writeLogMessage(tag: String, message: String) {
Log.d(tag, message)
}
// ios
actual fun writeLogMessage(tag: String, message: String) {
print(tag + " : " + message)
}
Kotlin/MPP
expect - actual
23. // common
expect fun writeLogMessage(tag: String, message: String)
// android
actual fun writeLogMessage(tag: String, message: String) {
Log.d(tag, message)
}
// ios
actual fun writeLogMessage(tag: String, message: String) {
print(tag + " : " + message)
}
expect - actual
Kotlin/MPP
24. // common
expect fun platformName(): String
// android
actual fun platformName(): String {
return android.os.Build.MANUFACTURER +
" " +
android.os.Build.MODEL
}
// ios
// system frameworks are pre-imported
import platform.UIKit.UIDevice
actual fun platformName(): String {
return UIDevice.currentDevice.systemName() +
" " +
UIDevice.currentDevice.systemVersion
}
expect - actual
Kotlin/MPP
25. // common
expect fun platformName(): String
// android
actual fun platformName(): String {
return android.os.Build.MANUFACTURER +
" " +
android.os.Build.MODEL
}
// ios
// system frameworks are pre-imported
import platform.UIKit.UIDevice
actual fun platformName(): String {
return UIDevice.currentDevice.systemName() +
" " +
UIDevice.currentDevice.systemVersion
}
expect - actual
Kotlin/MPP
26. // common
package example
object Object {
val field = "A"
}
interface Interface {
fun iMember() {}
}
class Clazz : Interface {
fun method(someClass: SomeObjcClass): ULong? = 42UL
}
fun acceptFun(block: (String) -> String?)
= block("block is lambda!")
fun supplyFun() : (String) -> String? = { "$it is cool!" }
ObjC/Swift interop
Kotlin/MPP
27. // common
package example
object Object {
val field = "A"
}
interface Interface {
fun iMember() {}
}
class Clazz : Interface {
fun method(someClass: SomeObjcClass): ULong? = 42UL
}
fun acceptFun(block: (String) -> String?)
= block("block is lambda!")
fun supplyFun() : (String) -> String? = { "$it is cool!" }
ObjC/Swift interop
Kotlin/MPP
28. // ios
import Foundation
import Demo
let kotlinObject = Object()
assert(kotlinObject === Object(),
"Kotlin object has only one instance")
let field = Object().field
let clazz = Clazz()
clazz.method(someClass: SomeObjcClass())
let ret = LibKt.acceptFun { "($0) Kotlin is fun" }
if (ret != nil) {
print(ret!)
}
ObjC/Swift interop
Kotlin/MPP
29. // ios
import Foundation
import Demo
let kotlinObject = Object()
assert(kotlinObject === Object(),
"Kotlin object has only one instance")
let field = Object().field
let clazz = Clazz()
clazz.method(someClass: SomeObjcClass())
let ret = LibKt.acceptFun { "($0) Kotlin is fun" }
if (ret != nil) {
print(ret!)
}
ObjC/Swift interop
Kotlin/MPP
30. Data model
Persistence
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Networking
Share business logic
Kotlin/MPP
31. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Networking Persistence
Share business logic
Kotlin/MPP
32. Networking Kotlin/MPP
Ktor is a framework for building asynchronous
servers and clients in connected systems using
the powerful Kotlin programming language.
Ktor directly supports Raw Sockets, HTTP Clients
and WebSockets. Using Raw Sockets it is possible
to implement clients with higher level protocols.
https://ktor.io/clients/index.html
37. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
38. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Networking Persistence
Share business logic
Kotlin/MPP
41. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
42. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
43. Kotlin/MPPData model
1. use classes that are available in common
2. expect in common, actual in platform impl.
Use cases
sealed classes are not as useful on iOS
as on Android
)
44. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
45. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
47. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
48. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
56. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
57. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
59. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
60. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
66. Data model
Use cases
Utilities
MVx
(P, VM, I, U)
Unit and
integr.
tests
UI UI tests
(interop w/ platform)
Wiring up
(DI, SL)
Serialization
Kotlin +
Persistence
Share business logic
Kotlin/MPP
Networking
71. Multithreading
Kotlin/MPP
Bad news: you need to deal with
• object freezing and InvalidMutabilityException
• Workers
• @ThreadLocal / @SharedGlobal
• AtomicRef
• coroutines that run only on main thread
If you want to use it today
72. Bad news: you need to deal with
• object freezing and InvalidMutabilityException
• Workers
• @ThreadLocal / @SharedGlobal
• AtomicRef
• coroutines that run only on main thread
Multithreading
Kotlin/MPP
If you want to use it today
74. Multithreading
Kotlin/MPP
If you want to use it today
Good news:
• in most cases you need async, not MT
• coroutines are planned to be reworked
to support MT in K/N
75. iOS specifics
Kotlin/MPP
• K/N compiler produces .framework (or static .a)
• Emits DWARF (full debug support in Xcode)
• AppCode supports* completion and debugging
• system frameworks, like UIKit, are pre-linked
and can be used out of the box
• community CocoaPods plugin**
* almost. WIP
** https://github.com/AlecStrong/kotlin-native-cocoapods
76. MPP Platform
native code
only primitives
or RCTConvert /
RCTDeviceEventEmitter
via C interface
only primitives
or BasicMethodChannel
iOS: generates real
ObjC headers
in .framework
How K/MPP is different (IMO)
77. How K/MPP is different (IMO)
is a lower level language
proper replacement for C++
78. How K/MPP is different (IMO)
is a lower level language
proper replacement for C++
79. How K/MPP is different (IMO)
are all about about unified UI
and reducing development cycle (hot reload)
which is a perfectly valid case
80. How K/MPP is different
Kotlin/MPP
(IMO)
is an application level programming system
which aims to be a foundation
for shared business logic layer
but within a native app
81. How K/MPP is different (IMO)
+
https://tech.olx.com/fast-prototypes-with-flutter-kotlin-native-d7ce5cfeb5f1
82. How K/MPP is different (IMO)
https://tech.olx.com/fast-prototypes-with-flutter-kotlin-native-d7ce5cfeb5f1
83. Main issues
Kotlin/MPP
• K/N compiler performance
๏ compilation for iOS is slow and not incremental
๏ Android Instant Run is fine ✅
• IDEs and plugins are not perfect
๏ and their versions often don't match
๏ …but we are getting there
• Multithreading is not straightforward
• Bunch of other lesser and bigger annoying things
you find when working with new technology
85. Question of the day
• Under active development
• Well-known adopters and contributors
…and others
SQLDelight
CocoaPods plugin Timber
Stately
DroidCon app
86. Question of the day
• Under active development
• Well-known adopters and contributors
• Kotlin team is actively helping
87. Question of the day
• Under active development
• Well-known adopters and contributors
• Kotlin team is actively helping
• Mobile support is Tier 1
• No bridge == native performance
• Slack channel where you can ask anything
https://slack.kotlinlang.org/