Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Challenges of Building Kotlin Multiplatform Libraries

Mohit S
March 25, 2022

Challenges of Building Kotlin Multiplatform Libraries

Mohit S

March 25, 2022
Tweet

More Decks by Mohit S

Other Decks in Programming

Transcript

  1. Mohit Sarveiya
    Building Kotlin Multiplatform Libraries
    @heyitsmohit

    View full-size slide

  2. Building Kotlin Multiplatform Libraries
    ● Setting up KMM project

    ● CI Challenges

    ● API Design Challenges

    View full-size slide

  3. Why Kotlin Multiplatform?
    Android

    Kotlin/JVM
    iOS

    Swift/LLVM
    Web

    JS

    View full-size slide

  4. Why Kotlin Multiplatform?
    API API API

    View full-size slide

  5. Why Kotlin Multiplatform?
    Retrofit Ajax Alamofire

    View full-size slide

  6. Why Kotlin Multiplatform?
    Room/SQL Delight Core Data

    View full-size slide

  7. Why Kotlin Multiplatform?
    Business Logic Business Logic Business Logic

    View full-size slide

  8. Why Kotlin Multiplatform?
    MVP/MVVM/MVI ReactJs VIPER

    View full-size slide

  9. Why Kotlin Multiplatform?
    Shared code

    View full-size slide

  10. Why Kotlin Multiplatform?
    API Business Logic Analytics
    Cache

    View full-size slide

  11. Setting up KMM Project

    View full-size slide

  12. Use Case
    Show platform name
    Hello

    Android

    View full-size slide

  13. Hello

    iOS
    Use Case
    9:41
    Show platform name

    View full-size slide

  14. Greeter
    Use Case

    View full-size slide

  15. How to create Multiplatform app

    View full-size slide

  16. Plugin
    https:
    //
    plugins.jetbrains.com/plugin/14936-kotlin-multiplatform-mobile

    View full-size slide

  17. Project Setup
    Shared

    View full-size slide

  18. Project Setup
    Shared
    Android App

    View full-size slide

  19. Project Setup
    Shared
    Android App iOS App
    XCode Project

    View full-size slide

  20. Project Setup
    Shared
    Android App iOS App

    View full-size slide

  21. Project Setup
    Shared
    Android App iOS App
    Framework

    View full-size slide

  22. Project Setup
    Shared
    Android App iOS App

    View full-size slide

  23. Shared Module Structure

    View full-size slide

  24. Shared Module
    Shared
    src
    commonMain

    View full-size slide

  25. Shared Module
    Shared
    src
    commonMain
    androidMain

    View full-size slide

  26. Shared Module
    Shared
    src
    commonMain
    androidMain
    iOSMain

    View full-size slide

  27. Greeter
    Use Case

    View full-size slide

  28. Common
    Shared Module
    Android iOS
    Platform name

    View full-size slide

  29. Common
    expect class Platform() {

    val platform: String

    }

    View full-size slide

  30. Common
    expect class Platform() {

    val platform: String

    }

    View full-size slide

  31. Common
    expect class Platform() {

    val platform: String

    }

    View full-size slide

  32. Common
    expect class Platform() {

    val platform: String

    }

    Common

    View full-size slide

  33. Common
    Android
    Android iOS
    Platform name

    View full-size slide

  34. Android
    actual class Platform actual constructor() {

    actual val platform: String = ”Android”

    }

    View full-size slide

  35. Android
    actual class Platform actual constructor() {

    actual val platform: String = ”Android”

    }

    View full-size slide

  36. Android
    actual class Platform actual constructor() {

    actual val platform: String = ”Android”

    }

    View full-size slide

  37. Android
    actual class Platform actual constructor() {

    actual val platform: String = ”Android”

    }

    Common
    Android

    View full-size slide

  38. Common
    iOS
    Android iOS
    Platform name

    View full-size slide

  39. iOS
    actual class Platform actual constructor() {

    actual val platform: String = “iOS”

    }

    View full-size slide

  40. Common
    Shared Module
    Android iOS
    Platform name

    View full-size slide

  41. Common
    class Greeter {

    fun greet(): String {

    return "Hello ${Platform().platform}!"

    }

    }

    View full-size slide

  42. Common
    class Greeter {

    fun greet(): String {

    return "Hello ${Platform().platform}!"

    }

    }

    View full-size slide

  43. Using Shared Module

    View full-size slide

  44. Project Setup
    Shared
    Android App iOS App

    View full-size slide

  45. Use Case
    Show platform name
    Hello

    Android

    View full-size slide

  46. Android App
    class MainActivity : AppCompatActivity() {

    }

    View full-size slide

  47. Android App
    class MainActivity : AppCompatActivity() {

    fun onCreate(
    ...
    ) {

    val greeting = Greeter().greet()



    }

    }

    View full-size slide

  48. Android App
    class MainActivity : AppCompatActivity() {

    fun onCreate(
    ...
    ) {

    val greeting = Greeter().greet()

    textView.text = greeting



    }

    }

    View full-size slide

  49. Android App
    class Greeter {

    ...


    }
    Common Source Build

    View full-size slide

  50. Use Case
    Hello

    Android

    View full-size slide

  51. Android App
    class MainActivity : AppCompatActivity() {

    fun onCreate(
    ...
    ) {

    val greeting = Greeter().greet()

    textView.text = greeting



    }

    }

    View full-size slide

  52. Hello

    iOS
    Use Case
    9:41
    Show platform name

    View full-size slide

  53. iOS App
    class Greeter {

    ...


    }
    Common Source Build Framework

    View full-size slide

  54. iOS App
    import SwiftUI

    import shared

    View full-size slide

  55. iOS App
    import SwiftUI

    import shared

    func greet()
    ->
    String {

    return Greeting().greeting()

    }

    View full-size slide

  56. iOS App
    import SwiftUI

    import shared

    struct ContentView: View {

    var body: some View {

    }

    }

    View full-size slide

  57. iOS App
    import SwiftUI

    import shared

    struct ContentView: View {

    var body: some View {

    Text(greet())

    }

    }

    View full-size slide

  58. Hello

    iOS
    Use Case
    9:41
    Show platform name

    View full-size slide

  59. Inside Objective-C Framework

    View full-size slide

  60. iOS Framework
    class Greeter {

    ...


    }
    Common Source Build Framework

    View full-size slide

  61. iOS Framework
    import SwiftUI

    import shared

    func greet()
    ->
    String {

    return Greeting().greeting()

    }

    View full-size slide

  62. iOS Framework
    Shared Base
    Shared Platform Shared Greeting

    View full-size slide

  63. Shared Base
    __attribute__((swift_name("KotlinBase")))


    @interface SharedBase : NSObject


    ...


    @end;


    View full-size slide

  64. Shared Base
    __attribute__((swift_name("KotlinBase")))


    @interface SharedBase : NSObject


    ...


    @end;


    View full-size slide

  65. iOS
    actual class Platform actual constructor() {

    actual val platform: String = “iOS”

    }

    View full-size slide

  66. Mappings
    https:
    //
    kotlinlang.org/docs/native-objc-interop.html#mappings

    View full-size slide

  67. Shared Platform
    __
    attribute
    __
    ((swift_name(“Platform")))

    @interface SharedPlatform : SharedBase

    ...


    @end;

    View full-size slide

  68. Shared Platform
    __
    attribute
    __
    ((swift_name(“Platform")))

    @interface SharedPlatform : SharedBase

    @property (readonly) NSString *platform

    @end;

    View full-size slide

  69. Common
    class Greeter {

    fun greet(): String {

    return "Hello ${Platform().platform}!"

    }

    }

    View full-size slide

  70. Common
    @interface SharedGreeting : SharedBase

    - (NSString *)greeting
    __
    attribute
    __
    ((swift_name("greeting()")));

    @end;

    View full-size slide

  71. Android & iOS Shared Modules

    View full-size slide

  72. Use Case
    Hello

    Android 29

    View full-size slide

  73. Shared Module
    Shared
    src
    commonMain
    androidMain
    iOSMain

    View full-size slide

  74. Android
    actual class Platform actual constructor() {

    actual val platform: String =

    “Android ${android.os.Build.VERSION.SDK_INT}"

    }

    View full-size slide

  75. Hello

    iOS 14.4
    Use Case
    9:41

    View full-size slide

  76. Shared Module
    Shared
    src
    commonMain
    androidMain
    iOSMain

    View full-size slide

  77. iOS
    import platform.UIKit.UIDevice

    actual class Platform actual constructor() {

    actual val platform: String =

    UIDevice.currentDevice.systemName() + " " +

    UIDevice.currentDevice.systemVersion

    }

    View full-size slide

  78. iOS
    import platform.UIKit.UIDevice

    actual class Platform actual constructor() {

    actual val platform: String =

    UIDevice.currentDevice.systemName() + " " +

    UIDevice.currentDevice.systemVersion

    }

    View full-size slide

  79. Summary
    ● How to build KMM project

    ● Shared Module Setup

    ● Inside Shared Framework

    View full-size slide

  80. CI Challenges

    View full-size slide

  81. Swift Package Manager

    View full-size slide

  82. Framework
    KMM Library

    View full-size slide

  83. Swift Package Manager
    KMM Library

    View full-size slide

  84. Multiplatform Swift Package
    ● Gradle plugin

    ● Generate XCFramework

    View full-size slide

  85. Multiplatform Swift Package
    id("com.chromaticnoise.multiplatform-swiftpackage") version "2.0.3"

    View full-size slide

  86. Multiplatform Swift Package
    multiplatformSwiftPackage {

    swiftToolsVersion(“5.5")

    targetPlatforms {

    iOS { v("13") }

    }

    }

    View full-size slide

  87. Multiplatform Swift Package
    ./gradlew createSwiftPackage

    View full-size slide

  88. KMM Library XCEFramework

    View full-size slide

  89. Projects/KMMProject
    Code ! Issues Pull Requests
    KMMLibrary.xcframework
    1 commit
    4c28f942 13 hours ago
    Package.swift
    KMMLibrary-1.0.zip
    README.md

    View full-size slide

  90. Choose Package Repository
    Search or enter package repository URL
    Name Last Updated Owner
    Projects(Github)
    KMMPackage Today 13:00 user

    View full-size slide

  91. Add Package to Project
    Choose package and targets
    Kind Add to Target
    KMMLibrary Library TestKMMLibrary
    Package Product

    View full-size slide

  92. Steps
    ● Create XCEFramework

    ● Consume using Swift Package Manager

    View full-size slide

  93. Build Automation

    View full-size slide

  94. KMM Library
    bdae142
    ..
    main
    50157a
    ..
    d89f145
    ..
    f0ddfb
    ..

    View full-size slide

  95. bdae142
    ..
    main
    50157a
    ..
    d89f145
    ..
    f0ddfb
    ..

    View full-size slide

  96. KMM Library
    Jar
    XCEFramework

    View full-size slide

  97. KMM Library
    Jar
    XCEFramework
    Artifactory

    View full-size slide

  98. Build Automation
    ● Setup CI to create artifcats

    ● Use artifacts from repository like Artifactory

    View full-size slide

  99. API Design Challenges

    View full-size slide

  100. Common
    fun getData(): Flow

    View full-size slide

  101. Android
    val flow = getData()

    flow.collect {



    }

    View full-size slide

  102. iOS
    getData(

    collector: T
    ##
    Kotlinx_coroutines_coreFlowCollector,

    completionHandler: (KotlinUnit?, Error?)
    ->
    Void

    )

    View full-size slide

  103. Common
    class CFlow internal constructor(

    val origin: Flow

    ) : Flow by origin {

    fun watch(block: (T)
    ->
    Unit) {

    }

    }

    View full-size slide

  104. Common
    class CFlow internal constructor(

    val origin: Flow

    ) : Flow by origin {

    fun watch(block: (T)
    ->
    Unit) {

    onEach { block(it) }

    launchIn(CoroutineScope(
    ...
    ))

    }

    }

    View full-size slide

  105. Common
    fun Flow.wrap(): CFlow = CFlow(this)

    View full-size slide

  106. iOS
    flow

    .wrap()

    .watch { data
    ->

    }

    View full-size slide

  107. Building Kotlin Multiplatform Libraries
    ● Setting up KMM project

    ● CI Challenges

    ● API Design Challenges

    View full-size slide

  108. Thank You!
    www.codingwithmohit.com
    @heyitsmohit

    View full-size slide