Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Challenges of Building Kotlin Multiplatform Lib...
Search
Mohit S
March 25, 2022
Programming
1
380
Challenges of Building Kotlin Multiplatform Libraries
Mohit S
March 25, 2022
Tweet
Share
More Decks by Mohit S
See All by Mohit S
Guide to Improving Compose Performance
heyitsmohit
0
110
Building Shared UIs across Platforms with Compose
heyitsmohit
1
450
Building Multiplatform Apps with Compose
heyitsmohit
2
390
Building StateFlows with Jetpack Compose
heyitsmohit
6
1.7k
Building Android Testing Infrastructure
heyitsmohit
1
360
Migrating to Kotlin State & Shared Flows
heyitsmohit
1
650
Using Square Workflow for Android & iOS
heyitsmohit
1
350
Building Android Infrastructure Teams at Scale
heyitsmohit
3
270
Strategies for Migrating to Jetpack Compose
heyitsmohit
2
480
Other Decks in Programming
See All in Programming
Modern Functional Fluent CFML REST by Luis Majano
ortus24
0
130
Pythonによるイベントソーシングへの挑戦と現状に対する考察 / Challenging Event Sourcing with Python and Reflections on the Current State
nrslib
3
890
RemixとCloudflare Stack におけるFile Upload
ossamoon
1
120
AWS Lambda Web Adapterを活用する新しいサーバーレスの実装パターン
tmokmss
6
5.5k
Frontend Magic mit CSS Houdini
joergneumann
0
420
文化が生産性を作る
jimpei
2
500
CDKを活用した 大規模コンテナ移行 プロジェクトの紹介
yoyoyopg
0
240
C#および.NETに対する誤解をひも解く
ymd65536
0
230
コードレビューと私の過去と未来
jxmtst
0
170
ROS 2のZenoh対応とZenohのROS 2対応
takasehideki
2
250
Micro Frontends for Java Microservices - dev2next 2024
mraible
PRO
0
190
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
6
230
Featured
See All Featured
The Power of CSS Pseudo Elements
geoffreycrofte
71
5.3k
Optimising Largest Contentful Paint
csswizardry
31
2.8k
Six Lessons from altMBA
skipperchong
26
3.4k
Building Better People: How to give real-time feedback that sticks.
wjessup
360
19k
Web Components: a chance to create the future
zenorocha
310
42k
A Philosophy of Restraint
colly
202
16k
WebSockets: Embracing the real-time Web
robhawkes
59
7.3k
A designer walks into a library…
pauljervisheath
201
24k
5 minutes of I Can Smell Your CMS
philhawksworth
202
19k
The Pragmatic Product Professional
lauravandoore
31
6.2k
Facilitating Awesome Meetings
lara
49
6k
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
37
1.7k
Transcript
Mohit Sarveiya Building Kotlin Multiplatform Libraries @heyitsmohit
Building Kotlin Multiplatform Libraries • Setting up KMM project •
CI Challenges • API Design Challenges
Why Kotlin Multiplatform? Android Kotlin/JVM iOS Swift/LLVM Web JS
Why Kotlin Multiplatform? API API API
Why Kotlin Multiplatform? Retrofit Ajax Alamofire
Why Kotlin Multiplatform? Room/SQL Delight Core Data
Why Kotlin Multiplatform? Business Logic Business Logic Business Logic
Why Kotlin Multiplatform? MVP/MVVM/MVI ReactJs VIPER
Why Kotlin Multiplatform? Shared code
Why Kotlin Multiplatform? API Business Logic Analytics Cache
Setting up KMM Project
Use Case Show platform name Hello Android
Hello iOS Use Case 9:41 Show platform name
Greeter Use Case
How to create Multiplatform app
Plugin https: // plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile
Project Setup Shared
Project Setup Shared Android App
Project Setup Shared Android App iOS App XCode Project
Project Setup Shared Android App iOS App
Project Setup Shared Android App iOS App Framework
Project Setup Shared Android App iOS App
Shared Module Structure
Shared Module Shared src commonMain
Shared Module Shared src commonMain androidMain
Shared Module Shared src commonMain androidMain iOSMain
Greeter Use Case
Common Shared Module Android iOS Platform name
Common expect class Platform() { val platform: String }
Common expect class Platform() { val platform: String }
Common expect class Platform() { val platform: String }
Common expect class Platform() { val platform: String } Common
Common Android Android iOS Platform name
Android actual class Platform actual constructor() { actual val platform:
String = ”Android” }
Android actual class Platform actual constructor() { actual val platform:
String = ”Android” }
Android actual class Platform actual constructor() { actual val platform:
String = ”Android” }
Android actual class Platform actual constructor() { actual val platform:
String = ”Android” } Common Android
Common iOS Android iOS Platform name
iOS actual class Platform actual constructor() { actual val platform:
String = “iOS” }
Common Shared Module Android iOS Platform name
Common class Greeter { fun greet(): String { return "Hello
${Platform().platform}!" } }
Common class Greeter { fun greet(): String { return "Hello
${Platform().platform}!" } }
Using Shared Module
Project Setup Shared Android App iOS App
Use Case Show platform name Hello Android
Android App class MainActivity : AppCompatActivity() { }
Android App class MainActivity : AppCompatActivity() { fun onCreate( ...
) { val greeting = Greeter().greet() } }
Android App class MainActivity : AppCompatActivity() { fun onCreate( ...
) { val greeting = Greeter().greet() textView.text = greeting } }
Android App class Greeter { ... } Common Source Build
Use Case Hello Android
Android App class MainActivity : AppCompatActivity() { fun onCreate( ...
) { val greeting = Greeter().greet() textView.text = greeting } }
Hello iOS Use Case 9:41 Show platform name
iOS App class Greeter { ... } Common Source Build
Framework
iOS App import SwiftUI import shared
iOS App import SwiftUI import shared func greet() -> String
{ return Greeting().greeting() }
iOS App import SwiftUI import shared struct ContentView: View {
var body: some View { } }
iOS App import SwiftUI import shared struct ContentView: View {
var body: some View { Text(greet()) } }
Hello iOS Use Case 9:41 Show platform name
Inside Objective-C Framework
iOS Framework class Greeter { ... } Common Source Build
Framework
iOS Framework import SwiftUI import shared func greet() -> String
{ return Greeting().greeting() }
iOS Framework Shared Base Shared Platform Shared Greeting
Shared Base __attribute__((swift_name("KotlinBase"))) @interface SharedBase : NSObject ... @end;
Shared Base __attribute__((swift_name("KotlinBase"))) @interface SharedBase : NSObject ... @end;
iOS actual class Platform actual constructor() { actual val platform:
String = “iOS” }
Mappings https: // kotlinlang.org/docs/native-objc-interop.html#mappings
Shared Platform __ attribute __ ((swift_name(“Platform"))) @interface SharedPlatform : SharedBase
... @end;
Shared Platform __ attribute __ ((swift_name(“Platform"))) @interface SharedPlatform : SharedBase
@property (readonly) NSString *platform @end;
Common class Greeter { fun greet(): String { return "Hello
${Platform().platform}!" } }
Common @interface SharedGreeting : SharedBase - (NSString *)greeting __ attribute
__ ((swift_name("greeting()"))); @end;
Android & iOS Shared Modules
Use Case Hello Android 29
Shared Module Shared src commonMain androidMain iOSMain
Android actual class Platform actual constructor() { actual val platform:
String = “Android ${android.os.Build.VERSION.SDK_INT}" }
Hello iOS 14.4 Use Case 9:41
Shared Module Shared src commonMain androidMain iOSMain
iOS import platform.UIKit.UIDevice actual class Platform actual constructor() { actual
val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion }
iOS import platform.UIKit.UIDevice actual class Platform actual constructor() { actual
val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion }
Summary • How to build KMM project • Shared Module
Setup • Inside Shared Framework
CI Challenges
Swift Package Manager
Framework KMM Library
Swift Package Manager KMM Library
Multiplatform Swift Package • Gradle plugin • Generate XCFramework
Multiplatform Swift Package id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"
Multiplatform Swift Package multiplatformSwiftPackage { swiftToolsVersion(“5.5") targetPlatforms { iOS {
v("13") } } }
Multiplatform Swift Package ./gradlew createSwiftPackage
KMM Library XCEFramework
Projects/KMMProject Code ! Issues Pull Requests KMMLibrary.xcframework 1 commit 4c28f942
13 hours ago Package.swift KMMLibrary-1.0.zip README.md
Choose Package Repository Search or enter package repository URL Name
Last Updated Owner Projects(Github) KMMPackage Today 13:00 user
Add Package to Project Choose package and targets Kind Add
to Target KMMLibrary Library TestKMMLibrary Package Product
Steps • Create XCEFramework • Consume using Swift Package Manager
Build Automation
KMM Library bdae142 .. main 50157a .. d89f145 .. f0ddfb
..
bdae142 .. main 50157a .. d89f145 .. f0ddfb ..
KMM Library Jar XCEFramework
KMM Library Jar XCEFramework Artifactory
Artifactory
Build Automation • Setup CI to create artifcats • Use
artifacts from repository like Artifactory
API Design Challenges
Flows
Common fun getData(): Flow<Data>
Android val flow = getData() flow.collect { }
iOS getData( collector: T ## Kotlinx_coroutines_coreFlowCollector, completionHandler: (KotlinUnit?, Error?) ->
Void )
Common class CFlow internal constructor( val origin: Flow ) :
Flow by origin { fun watch(block: (T) -> Unit) { } }
Common class CFlow internal constructor( val origin: Flow ) :
Flow by origin { fun watch(block: (T) -> Unit) { onEach { block(it) } launchIn(CoroutineScope( ... )) } }
Common fun Flow<T>.wrap(): CFlow<T> = CFlow(this)
iOS flow .wrap() .watch { data -> }
Building Kotlin Multiplatform Libraries • Setting up KMM project •
CI Challenges • API Design Challenges
Thank You! www.codingwithmohit.com @heyitsmohit