Mohit SarveiyaBuilding Kotlin Multiplatform Libraries@heyitsmohit
View Slide
Building Kotlin Multiplatform Libraries● Setting up KMM project● CI Challenges● API Design Challenges
Why Kotlin Multiplatform?AndroidKotlin/JVMiOSSwift/LLVMWebJS
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 AnalyticsCache
Setting up KMM Project
Use CaseShow platform nameHello Android
Hello iOSUse Case9:41Show platform name
GreeterUse Case
How to create Multiplatform app
Pluginhttps://plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile
Project SetupShared
Project SetupSharedAndroid App
Project SetupSharedAndroid App iOS AppXCode Project
Project SetupSharedAndroid App iOS App
Project SetupSharedAndroid App iOS AppFramework
Shared Module Structure
Shared ModuleSharedsrccommonMain
Shared ModuleSharedsrccommonMainandroidMain
Shared ModuleSharedsrccommonMainandroidMainiOSMain
CommonShared ModuleAndroid iOSPlatform name
Commonexpect class Platform() {val platform: String}
Commonexpect class Platform() {val platform: String}Common
CommonAndroidAndroid iOSPlatform name
Androidactual class Platform actual constructor() {actual val platform: String = ”Android”}
Androidactual class Platform actual constructor() {actual val platform: String = ”Android”}CommonAndroid
CommoniOSAndroid iOSPlatform name
iOSactual class Platform actual constructor() {actual val platform: String = “iOS”}
Commonclass Greeter {fun greet(): String {return "Hello ${Platform().platform}!"}}
Using Shared Module
Android Appclass MainActivity : AppCompatActivity() {}
Android Appclass MainActivity : AppCompatActivity() {fun onCreate(...) {val greeting = Greeter().greet()}}
Android Appclass MainActivity : AppCompatActivity() {fun onCreate(...) {val greeting = Greeter().greet()textView.text = greeting}}
Android Appclass Greeter {...}Common Source Build
Use CaseHello Android
iOS Appclass Greeter {...}Common Source Build Framework
iOS Appimport SwiftUIimport shared
iOS Appimport SwiftUIimport sharedfunc greet()->String {return Greeting().greeting()}
iOS Appimport SwiftUIimport sharedstruct ContentView: View {var body: some View {}}
iOS Appimport SwiftUIimport sharedstruct ContentView: View {var body: some View {Text(greet())}}
Inside Objective-C Framework
iOS Frameworkclass Greeter {...}Common Source Build Framework
iOS Frameworkimport SwiftUIimport sharedfunc greet()->String {return Greeting().greeting()}
iOS FrameworkShared BaseShared Platform Shared Greeting
Shared Base__attribute__((swift_name("KotlinBase")))@interface SharedBase : NSObject...@end;
Mappingshttps://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@interface SharedGreeting : SharedBase- (NSString *)greeting__attribute__((swift_name("greeting()")));@end;
Android & iOS Shared Modules
Use CaseHello Android 29
Androidactual class Platform actual constructor() {actual val platform: String = “Android ${android.os.Build.VERSION.SDK_INT}"}
Hello iOS 14.4Use Case9:41
iOSimport platform.UIKit.UIDeviceactual 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
FrameworkKMM Library
Swift Package ManagerKMM Library
Multiplatform Swift Package● Gradle plugin● Generate XCFramework
Multiplatform Swift Packageid("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"
Multiplatform Swift PackagemultiplatformSwiftPackage {swiftToolsVersion(“5.5")targetPlatforms {iOS { v("13") }}}
Multiplatform Swift Package./gradlew createSwiftPackage
KMM Library XCEFramework
Projects/KMMProjectCode ! Issues Pull RequestsKMMLibrary.xcframework1 commit4c28f942 13 hours agoPackage.swiftKMMLibrary-1.0.zipREADME.md
Choose Package RepositorySearch or enter package repository URLName Last Updated OwnerProjects(Github)KMMPackage Today 13:00 user
Add Package to ProjectChoose package and targetsKind Add to TargetKMMLibrary Library TestKMMLibraryPackage Product
Steps● Create XCEFramework● Consume using Swift Package Manager
Build Automation
KMM Librarybdae142..main50157a..d89f145..f0ddfb..
bdae142..main50157a..d89f145..f0ddfb..
KMM LibraryJarXCEFramework
KMM LibraryJarXCEFrameworkArtifactory
Artifactory
Build Automation● Setup CI to create artifcats● Use artifacts from repository like Artifactory
API Design Challenges
Flows
Commonfun getData(): Flow
Androidval flow = getData()flow.collect {}
iOSgetData(collector: T##Kotlinx_coroutines_coreFlowCollector, completionHandler: (KotlinUnit?, Error?)->Void)
Commonclass CFlow internal constructor(val origin: Flow) : Flow by origin {fun watch(block: (T)->Unit) {}}
Commonclass CFlow internal constructor(val origin: Flow) : Flow by origin {fun watch(block: (T)->Unit) {onEach { block(it) }launchIn(CoroutineScope(...))}}
Commonfun Flow.wrap(): CFlow = CFlow(this)
iOSflow.wrap().watch { data-> }
Thank You!www.codingwithmohit.com@heyitsmohit