$30 off During Our Annual Pro Sale. View Details »

Hi, have you met Kotlin Multiplatform | GDG Braunschweig

Hi, have you met Kotlin Multiplatform | GDG Braunschweig

Kotlin Multiplatform is getting more and more hype every day. It started as an experimental technology, then alpha, beta and now it's on the path of becoming stable.

We constantly read of new companies and teams that are using KMP for experiments and production projects alike. And we're left wondering: why pick KMP over any other cross-platform solution? How to approach it? And, most importantly, is it possible to start using it in existing projects?

In this talk, I'll answer these questions, clarifying all the doubts and making you ready to use and love Kotlin Multiplatform.

Marco Gomiero

September 14, 2023
Tweet

More Decks by Marco Gomiero

Other Decks in Programming

Transcript

  1. 👨💻 Senior Android Engineer @ TIER

    Google Developer Expert for Kotlin
    Marco Gomiero
    @marcoGomier
    Hi, have you met


    Kotlin
    Multiplatform?

    View Slide

  2. @marcoGomier
    “Classic” Cross Platform Solutions
    • All-in approach


    • Everything is shared, UI included


    • Different platforms have different patterns

    View Slide

  3. @marcoGomier
    Kotlin Multiplatform
    • Incremental approach


    • You choose what to share (even UI, if you want)

    View Slide

  4. @marcoGomier
    Common Kotlin
    Kotlin/JVM Kotlin/JS
    Kotlin/Native
    JVM


    Android
    Browser


    NodeJS
    iOS


    macOS


    watchOS


    tvOS


    Linux


    Windows
    Supported Platforms

    View Slide

  5. @marcoGomier
    Common Kotlin
    Kotlin/JVM Kotlin/JS
    Kotlin/Native
    JVM


    Android
    Browser


    NodeJS
    iOS


    macOS


    watchOS


    tvOS


    Linux


    Windows
    Mobile + JVM

    View Slide

  6. @marcoGomier
    Common and Platform-specific code
    • Write regular Kotlin code in the
    common source set


    • Platform-specific code goes into
    platform source sets

    View Slide

  7. @marcoGomier
    Platform-specific code
    • Expect/Actual


    View Slide

  8. @marcoGomier
    Expect/Actual
    https://kotlinlang.org/docs/multiplatform-connect-to-apis.html

    View Slide

  9. @marcoGomier
    Expect/Actual
    expect fun debugLog(tag: String, message: String)

    View Slide

  10. @marcoGomier
    expect fun debugLog(tag: String, message: String)
    import android.util.Log


    actual fun debugLog(tag: String, message: String) {


    Log.d(tag, message)


    }
    import platform.Foundation.NSLog


    actual fun debugLog(tag: String, message: String) {


    if (Platform.isDebugBinary) {


    NSLog("%s: %s", tag, message)


    }


    }

    View Slide

  11. @marcoGomier
    Platform-specific code
    • Expect/Actual


    • Interfaces


    View Slide

  12. @marcoGomier
    Interfaces
    interface HtmlParser {


    fun getTextFromHTML(html: String): String?


    }

    View Slide

  13. @marcoGomier
    import org.jsoup.Jsoup


    internal class JvmHtmlParser : HtmlParser {


    override fun getTextFromHTML(html: String): String? {


    return try {


    val doc = Jsoup.parse(html)


    doc.text()


    } catch (e: Throwable) {


    null


    }


    }


    }
    import shared


    import SwiftSoup


    class IosHtmlParser: HtmlParser {


    func getTextFromHTML(html: String) -> String? {


    do {


    let doc: Document = try SwiftSoup.parse(html)


    return try doc.text()


    } catch {


    return nil


    }


    }


    }
    interface HtmlParser {


    fun getTextFromHTML(html: String): String?


    }

    View Slide

  14. @marcoGomier
    Platform-specific code
    • Expect/Actual


    • Interfaces


    • Prefer interfaces, if possible

    View Slide

  15. @marcoGomier
    How it works?

    View Slide

  16. @marcoGomier
    shared
    androidApp
    .aar
    Android

    View Slide

  17. @marcoGomier
    shared
    androidApp iosApp
    .aar Framework
    iOS
    Android

    View Slide

  18. @marcoGomier
    XCFramework

    View Slide

  19. @marcoGomier
    NEW
    https://devstreaming-cdn.apple.com/videos/wwdc/2019/416h8485aty341c2/416/416_binary_frameworks_in_swift.pdf

    View Slide

  20. @marcoGomier https://devstreaming-cdn.apple.com/videos/wwdc/2019/416h8485aty341c2/416/416_binary_frameworks_in_swift.pdf
    NEW
    iOS mac
    OS
    watch
    OS
    tvOS

    View Slide

  21. @marcoGomier
    Kotlin
    ->
    Obj-c
    ->
    Swift

    View Slide

  22. @marcoGomier
    when (appState.newsState) {


    is NewsState.Loading
    ->
    {


    progressBar.visibility = View.VISIBLE


    ...

    }


    is NewsState.Error
    ->
    {


    errorButton.visibility = View.VISIBLE


    errorMessage.visibility = View.VISIBLE


    ...

    }


    is NewsState.Success
    ->
    {


    progressBar.visibility = View.GONE


    errorMessage.visibility = View.GONE


    recyclerView.visibility = View.VISIBLE


    ...

    }


    }


    View Slide

  23. @marcoGomier
    Some gotchas
    • No namespaces


    • No default parameters


    • Enums are not Swift-friendly (no values)


    • Sealed classes are simple classes


    • Coroutines and Flows

    View Slide

  24. @marcoGomier https://github.com/rickclephas/KMP-NativeCoroutines

    View Slide

  25. @marcoGomier https://github.com/touchlab/SKIE

    View Slide

  26. @marcoGomier https://github.com/icerockdev/moko-kswift

    View Slide

  27. @marcoGomier
    Make it a team effort

    View Slide

  28. @marcoGomier https://medium.com/@aoriani/list/writing-swiftfriendly-kotlin-multiplatform-apis-c51c2b317fce

    View Slide

  29. @marcoGomier
    New projects

    View Slide

  30. @marcoGomier
    Create a new app project

    View Slide

  31. @marcoGomier

    View Slide

  32. @marcoGomier

    View Slide

  33. @marcoGomier

    View Slide

  34. @marcoGomier
    shared
    androidApp
    Gradle Module
    Android

    View Slide

  35. @marcoGomier
    // settings.gradle.kts


    include(":shared")


    // build.gradle.kts


    implementation(project(":shared"))
    Android

    View Slide

  36. @marcoGomier
    shared
    androidApp iosApp
    Gradle Module Framework
    iOS
    Android

    View Slide

  37. @marcoGomier
    Regular Framework

    View Slide

  38. @marcoGomier
    Create a new app project

    View Slide

  39. @marcoGomier
    CocoaPods integration
    https://kotlinlang.org/docs/reference/native/cocoapods.html
    Pod::Spec.new do |spec|


    spec.name = 'shared'


    spec.version = '1.0'


    spec.homepage = 'Link to the Shared Module homepage'


    spec.source = { :http=> ''}


    spec.authors = ''


    spec.license = ''


    spec.summary = 'Some description for the Shared Module'


    spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework'


    spec.libraries = 'c++'


    spec.ios.deployment_target = '14.1'






    spec.pod_target_xcconfig = {


    'KOTLIN_PROJECT_PATH' => ':shared',


    'PRODUCT_MODULE_NAME' => 'shared',


    }



    spec.script_phases = [


    {


    :name => 'Build shared',


    :execution_position => :before_compile,


    :shell_path => '/bin/sh',


    :script => <<-SCRIPT


    if [ "YES" = "$OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED" ]; then


    echo "Skipping Gradle build task invocation due to OVERRIDE_KOTLIN_BUILD_IDE_SUPPORTED environment


    exit 0


    fi


    set -ev


    REPO_ROOT="$PODS_TARGET_SRCROOT"


    "$REPO_ROOT/../gradlew" -p "$REPO_ROOT" $KOTLIN_PROJECT_PATH:syncFramework \


    -Pkotlin.native.cocoapods.platform=$PLATFORM_NAME \


    -Pkotlin.native.cocoapods.archs="$ARCHS" \


    -Pkotlin.native.cocoapods.configuration="$CONFIGURATION"


    SCRIPT


    }


    ]



    end


    View Slide

  40. @marcoGomier
    iOSApp: Podfile
    https://kotlinlang.org/docs/reference/native/cocoapods.html
    target 'iosApp' do


    use_frameworks!


    platform :ios, '14.1'


    pod 'shared', :path => '../shared'


    end

    View Slide

  41. @marcoGomier
    shared
    androidApp iosApp
    Gradle Module Framework
    iOS
    Android

    View Slide

  42. @marcoGomier
    shared
    androidApp iosApp
    Framework
    Same Repository
    Gradle
    Module

    View Slide

  43. @marcoGomier
    Existing projects

    View Slide

  44. @marcoGomier
    🙅
    shared
    androidApp iosApp
    Gradle
    Module
    Framework
    Same Repository
    Existing projects

    View Slide

  45. @marcoGomier
    Create a new library project

    View Slide

  46. @marcoGomier

    View Slide

  47. @marcoGomier
    Common Kotlin
    Android App iOS App
    .aar XCFramework

    View Slide

  48. @marcoGomier
    Common Kotlin
    Android App iOS App
    .aar XCFramework

    Android App Repository
    KMP Repository
    iOs App Repository

    View Slide

  49. @marcoGomier
    How to publish: Android

    View Slide

  50. @marcoGomier
    Setup a Maven repository to share the artifacts: build.gradle.kts
    plugins {


    //...


    id("maven-publish")


    }


    group = "com.prof18.hn.foundation"


    version = "1.0"


    publishing {


    repositories {


    maven {


    credentials {


    username = "username"


    password = "pwd"


    }


    url = URI.create("https://mymavenrepo.it")


    }


    }


    }

    View Slide

  51. @marcoGomier
    Publish the artifacts
    ./gradlew publish


    View Slide

  52. @marcoGomier
    Publish the artifacts
    ./gradlew publish


    ./gradlew publishToMavenLocal


    View Slide

  53. @marcoGomier
    How to publish: iOS

    View Slide

  54. @marcoGomier
    🥵

    View Slide

  55. @marcoGomier
    XCFramework

    View Slide

  56. @marcoGomier
    Build an XCFramework
    https://kotlinlang.org/docs/multiplatform-build-native-binaries.html#build-xcframeworks
    import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework


    val libName = "LibraryName"


    kotlin {


    val xcFramework = XCFramework(libName)


    ios {


    binaries.framework(libName) {


    xcFramework.add(this)


    }


    }


    ...


    }

    View Slide

  57. @marcoGomier
    XCFramework: Gradle tasks
    assemble${libName}XCFramework


    assemble${libName}DebugXCFramework


    assemble${libName}ReleaseXCFramework

    View Slide

  58. @marcoGomier
    Build an XCFramework

    View Slide

  59. @marcoGomier https://github.com/touchlab/KMMBridge

    View Slide

  60. @marcoGomier https://github.com/prof18/kmp-framework-bundler

    View Slide

  61. @marcoGomier
    Where to start

    View Slide

  62. @marcoGomier
    shared
    androidApp iosApp
    Gradle
    Module
    Framework
    Same Repository
    New projects

    View Slide

  63. @marcoGomier
    🙅
    shared
    androidApp iosApp
    Gradle
    Module
    Framework
    Same Repository
    Existing projects

    View Slide

  64. @marcoGomier
    💡 Create a library!

    View Slide

  65. @marcoGomier
    • Boring code to write multiple times


    • Code/feature that centralizes the source of truth


    • Code/feature that can be gradually extracted
    Where to start?

    View Slide

  66. @marcoGomier
    • DTOs


    • Common Models


    • Utility methods


    • Analytics



    . . .
    Where to start?

    View Slide

  67. @marcoGomier
    Start little

    View Slide

  68. @marcoGomier
    Start little
    Go bigger
    then

    View Slide

  69. @marcoGomier
    Start little then go bigger
    • Validate the process with “little” effort


    • Then you can go bigger and share more “features”

    View Slide

  70. @marcoGomier
    Ecosystem

    View Slide

  71. @marcoGomier
    • Networking: Ktor, Apollo


    • Persistence: SQLDelight, multiplatform-settings, Realm


    • Serialization: kotlinx.serialization


    • Dependency Injection: Koin, Kodein, kotlin-inject


    • Asynchronous: Coroutines, Reaktive


    • Date/Time: kotlinx-datetime


    • Logging: Kermit, Napier
    Common Libraries
    And much more
    ...

    View Slide

  72. @marcoGomier
    https://github.com/AAkira/Kotlin-Multiplatform-Libraries
    https://github.com/terrakok/kmp-awesome

    View Slide

  73. @marcoGomier https://github.com/touchlab/xcode-kotlin

    View Slide

  74. @marcoGomier https://github.com/touchlab/xcode-kotlin

    View Slide

  75. @marcoGomier https://github.com/touchlab/xcode-kotlin

    View Slide

  76. @marcoGomier https://github.com/touchlab/CrashKiOS

    View Slide

  77. @marcoGomier https://github.com/touchlab/CrashKiOS

    View Slide

  78. @marcoGomier
    Conclusions

    View Slide

  79. @marcoGomier
    • Kotlin Multiplatform
    ! =
    Cross Platform


    • Beta stage, Stable late 2023


    Conclusions

    View Slide

  80. @marcoGomier https://www.droidcon.com/2023/07/31/10-myths-about-crossplatform-mobile-development-with-kotlin/

    View Slide

  81. @marcoGomier
    • Kotlin Multiplatform
    ! =
    Cross Platform


    • Beta stage, Stable late 2023


    • It’s the future


    • It’s a joint and team approach
    Conclusions

    View Slide

  82. Bibliography / Useful Links
    • https:
    //
    kotlinlang.org/docs/multiplatform.html


    • https:
    //
    kotlinlang.org/docs/native-overview.html


    • https:
    //
    kotlinlang.org/docs/js-overview.html


    • https:
    //
    kotlinlang.org/docs/multiplatform-share-on-platforms.html


    • https:
    //
    kotlinlang.org/docs/multiplatform-connect-to-apis.html


    • https:
    //
    devstreaming-cdn.apple.com/videos/wwdc/2019/416h8485aty341c2/416/416_binary_frameworks_in_swift.pdf


    • https:
    //
    developer.apple.com/videos/play/wwdc2019/416/


    • https:
    //
    medium.com/@aoriani/list/writing-swiftfriendly-kotlin-multiplatform-apis-c51c2b317fce


    • https:
    //
    kotlinlang.org/docs/native-objc-interop.html


    • https:
    //
    speakerdeck.com/kpgalligan/kotlinconf-2023-kotlin-mobile-multiplatform-for-teams


    • https:
    //
    speakerdeck.com/kpgalligan/sdk-design-and-publishing-for-kotlin-multiplatform-mobile


    • https:
    //
    kotlinlang.org/docs/reference/native/cocoapods.html


    • https:
    //
    kotlinlang.org/docs/multiplatform-build-native-binaries.html#build-xcframeworks


    • https:
    //
    github.com/touchlab/KMMBridge


    • https:
    //
    github.com/prof18/kmp-framework-bundler


    • https:
    //
    github.com/touchlab/xcode-kotlin


    • https:
    //
    github.com/terrakok/kmp-awesome


    • https:
    //
    github.com/AAkira/Kotlin-Multiplatform-Libraries


    • https:
    //
    github.com/touchlab/CrashKiOS


    • https:
    //
    www.droidcon.com/2023/07/31/10-myths-about-crossplatform-mobile-development-with-kotlin/

    View Slide

  83. @marcoGomier
    Thank you!
    > Twitter: @marcoGomier

    > Github: prof18

    > Website: marcogomiero.com

    > Mastodon: androiddev.social/@marcogom
    👨💻 Senior Android Engineer @ TIER

    Google Developer Expert for Kotlin
    Marco Gomiero

    View Slide