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

Hi, have you met Kotlin Multiplatform - ADI x GDG Pisa - Android Days: Day 1

Hi, have you met Kotlin Multiplatform - ADI x GDG Pisa - Android Days: Day 1

Kotlin Multiplatform is getting more and more hype every day, even if it’s still in alpha. We constantly read of new companies and teams that are trying KMP for experiments and production projects alike. And we’re left wondering: it safe to do so? Why picking KMP over any another 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 to these questions, clarifying all the doubts and making you ready to use and love Kotlin Multiplatform.

9da5d5cc4b6a9f28058152e28364b02a?s=128

Marco Gomiero

October 30, 2021
Tweet

More Decks by Marco Gomiero

Other Decks in Programming

Transcript

  1. Marco Gomiero ADI x GDG Pisa - Android Days Hi,

    have you met Kotlin Multiplatform?
  2. ADI x GDG Pisa - Android Days - @marcoGomier Marco

    Gomiero 👨💻 Android Engineer @ TIER 🛴 🇩🇪 🇮🇹 
 Google Developer Expert for Kotlin 
 🍻 Co-Lead @ GDG Venezia > Twitter: @marcoGomier 
 > Github: prof18 
 > Website: marcogomiero.com
  3. ADI x GDG Pisa - Android Days - @marcoGomier Kotlin

    Multiplatform
  4. ADI x GDG Pisa - Android Days - @marcoGomier “Classic”

    Cross Platform Solutions React Native Flutter
  5. ADI x GDG Pisa - Android Days - @marcoGomier Unify

    UI declaration across platforms
  6. ADI x GDG Pisa - Android Days - @marcoGomier React

    Native: call native widgets through a “bridge”
  7. ADI x GDG Pisa - Android Days - @marcoGomier Flutter:

    uses its own widget
  8. ADI x GDG Pisa - Android Days - @marcoGomier •

    Cons: use of “middlemen”, custom widgets • Unifying UI declaration between platform is complicated • Different platforms have different patterns “Classic” Cross Platform Solutions
  9. ADI x GDG Pisa - Android Days - @marcoGomier •

    Not about compiling all code for all platforms • Share as much [NO UI] code as possible Kotlin Multiplatform
  10. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Kotlin/JVM Kotlin/JS Kotlin/Native Java Android Browser NodeJS Android NDK iOs macOS watchOS tvOS Linux Windows
  11. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Kotlin/JVM Kotlin/JS Kotlin/Native Java Android Browser NodeJS Android NDK iOs macOS watchOS tvOS Linux Windows Mobile App
  12. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Kotlin/JVM Kotlin/JS Kotlin/Native Java Android Browser NodeJS Android NDK iOs macOS watchOS tvOS Linux Windows Mobile & Desktop App + JVM Backend
  13. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Kotlin/JVM Kotlin/JS Kotlin/Native Java Android Browser NodeJS Android NDK iOs macOS watchOS tvOS Linux Windows Full Stack JS App
  14. ADI x GDG Pisa - Android Days - @marcoGomier •

    expect/actual mechanism • Declaration in common target and implementation in all specific targets • Works for functions, classes, interfaces, enumerations, properties, and annotations. Platform-specific APIs?
  15. ADI x GDG Pisa - Android Days - @marcoGomier Common

    expect fun debugLog(tag: String, message: String)
  16. ADI x GDG Pisa - Android Days - @marcoGomier Android

    expect fun debugLog(tag: String, message: String) import android.util.Log actual fun debugLog(tag: String, message: String) { Log.d(tag, message) }
  17. ADI x GDG Pisa - Android Days - @marcoGomier iOS

    expect fun debugLog(tag: String, message: String) import platform.Foundation.NSLog actual fun debugLog(tag: String, message: String) { if (Platform.isDebugBinary) { NSLog("%s: %s", tag, message) } }
  18. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Kotlin/JVM Kotlin/JS Kotlin/Native Java Android Browser NodeJS Android NDK iOs macOS watchOS tvOS Linux Windows Mobile App
  19. ADI x GDG Pisa - Android Days - @marcoGomier https://kotlinlang.org/lp/mobile/

  20. GDG Pisa - Android Days @marcoGomier How it works: new

    project
  21. ADI x GDG Pisa - Android Days - @marcoGomier shared

    androidApp Gradle Module Android
  22. ADI x GDG Pisa - Android Days - @marcoGomier //

    settings.gradle.kts include(":shared") // build.gradle.kts implementation(project(":shared")) Android
  23. ADI x GDG Pisa - Android Days - @marcoGomier shared

    androidApp iosApp Gradle Module Framework iOS
  24. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  25. ADI x GDG Pisa - Android Days - @marcoGomier embedAndSignAppleFrameworkForXcode

    https://blog.jetbrains.com/kotlin/2021/07/multiplatform-gradle-plugin-improved-for-connecting-kmm-modules/ packForXcode From Kotlin 1.5.20 iOS
  26. ADI x GDG Pisa - Android Days - @marcoGomier

  27. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  28. ADI x GDG Pisa - Android Days - @marcoGomier CocoaPods

    integration https://kotlinlang.org/docs/reference/native/cocoapods.html Pod :: Spec.new do |spec| spec.name = 'shared' spec.version = '1.0-SNAPSHOT' spec.homepage = 'Link to a Kotlin/Native module homepage' spec.source = { :git => "Not Published", :tag = > "Cocoapods/ #{ spec.name} #{ spec.authors = '' spec.license = '' spec.summary = 'Some description for a Kotlin/Native module' spec.static_framework = true spec.vendored_frameworks = "build/cocoapods/framework/shared.framework" spec.libraries = "c ++ " spec.module_name = " # { spec.name}_umbrella" spec.pod_target_xcconfig = { 'KOTLIN_TARGET[sdk=iphonesimulator*]' => 'ios_x64', 'KOTLIN_TARGET[sdk=iphoneos*]' => 'ios_arm', 'KOTLIN_TARGET[sdk=watchsimulator*]' => 'watchos_x86', 'KOTLIN_TARGET[sdk=watchos*]' => 'watchos_arm', 'KOTLIN_TARGET[sdk=appletvsimulator*]' = > 'tvos_x64', 'KOTLIN_TARGET[sdk=appletvos*]' => 'tvos_arm64', 'KOTLIN_TARGET[sdk=macosx*]' = > 'macos_x64' } spec.script_phases = [ { :name = > 'Build shared', :execution_position = > :before_compile, :shell_path => '/bin/sh', :script => < <- SCRIPT set -ev REPO_ROOT="$PODS_TARGET_SRCROOT" "$REPO_ROOT/ .. /gradlew" -p "$REPO_ROOT" :shared:syncFramework \ -Pkotlin.native.cocoapods.target=$KOTLIN_TARGET \ -Pkotlin.native.cocoapods.configuration=$CONFIGURATION \ -Pkotlin.native.cocoapods.cflags="$OTHER_CFLAGS" \ -Pkotlin.native.cocoapods.paths.headers="$HEADER_SEARCH_PATHS" \ -Pkotlin.native.cocoapods.paths.frameworks="$FRAMEWORK_SEARCH_PATHS" SCRIPT } ] end
  29. ADI x GDG Pisa - Android Days - @marcoGomier iOS

    Project: Podfile pod 'shared', :path => ' .. /shared'
  30. ADI x GDG Pisa - Android Days - @marcoGomier shared

    androidApp iosApp Gradle Module Framework Same Repository Same Repository
  31. ADI x GDG Pisa - Android Days - @marcoGomier Conference

    Name - @marcoGomier . └── kmm-project ├── androidApp ├── iosApp └── shared Same Repository
  32. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/prof18/MoneyFlow

  33. GDG Pisa - Android Days @marcoGomier How it works: existing

    project
  34. ADI x GDG Pisa - Android Days - @marcoGomier Conference

    Name - @marcoGomier Photo by Ashkan Forouzani on Unsplash 🙅 shared androidApp iosApp Gradle Module Framework Same Repository
  35. ADI x GDG Pisa - Android Days - @marcoGomier Photo

    by Erwan Hesry on Unsplash 💡 Create a library!
  36. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Android App iOs App .aar Framework 
 Maven 
 Cocoa Repo
  37. ADI x GDG Pisa - Android Days - @marcoGomier Common

    Kotlin Android App iOs App .aar Framework 
 Maven 
 Cocoa Repo Android App Repository KMP Repository iOs App Repository
  38. GDG Pisa - Android Days @marcoGomier How to publish: Android

  39. ADI x GDG Pisa - Android Days - @marcoGomier plugins

    { //.. . id("maven-publish") } group = "com.prof18.hn.foundation" version = "1.0" publishing { repositories { maven{ credentials { username = "username" password = "pwd" } url = url("https: // mymavenrepo.it") } } } Setup a Maven repository to share the artifacts: build.gradle.kts
  40. ADI x GDG Pisa - Android Days - @marcoGomier Publish

    the artifacts ./gradlew publish
  41. ADI x GDG Pisa - Android Days - @marcoGomier Publish

    the artifacts ./gradlew publish ./gradlew publishToMavenLocal
  42. GDG Pisa - Android Days @marcoGomier How to publish: iOS

  43. ADI x GDG Pisa - Android Days - @marcoGomier 🥵

  44. ADI x GDG Pisa - Android Days - @marcoGomier embedAndSignAppleFrameworkForXcode

    packForXcode CocoaPods integration
  45. ADI x GDG Pisa - Android Days - @marcoGomier 🤔

  46. ADI x GDG Pisa - Android Days - @marcoGomier XCFramework

  47. ADI x GDG Pisa - Android Days - @marcoGomier NEW

    https://devstreaming-cdn.apple.com/videos/wwdc/2019/416h8485aty341c2/416/416_binary_frameworks_in_swift.pdf
  48. ADI x GDG Pisa - Android Days - @marcoGomier https://devstreaming-cdn.apple.com/videos/wwdc/2019/416h8485aty341c2/416/416_binary_frameworks_in_swift.pdf

    NEW iOS mac OS watch OS tvOS
  49. ADI x GDG Pisa - Android Days - @marcoGomier XCFramework

    Official Support from Kotlin 1.5.30 https://kotlinlang.org/docs/whatsnew1530.html#support-for-xcframeworks
  50. ADI x GDG Pisa - Android Days - @marcoGomier XCFramework

    prior to Kotlin 1.5.30
  51. ADI x GDG Pisa - Android Days - @marcoGomier XCFramework

    prior to Kotlin 1.5.30 https: / / www.marcogomiero.com/posts/2021/build-xcframework-kmp/
  52. ADI x GDG Pisa - Android Days - @marcoGomier XCFramework:

    build.gradle.kts https://github.com/prof18/shared-hn-android-ios-backend/blob/main/hn-foundation/build.gradle.kts import org.jetbrains.kotlin.gradle.plugin.mpp.apple.XCFramework val libName = "LibraryName" kotlin { val xcFramework = XCFramework(libName) ios { binaries.framework(libName) { xcFramework.add(this) } } ... }
  53. ADI x GDG Pisa - Android Days - @marcoGomier assemble${libName}XCFramework

    assemble${libName}DebugXCFramework assemble${libName}ReleaseXCFramework XCFramework: Gradle tasks
  54. ADI x GDG Pisa - Android Days - @marcoGomier .

    ├── build ├── XCFrameworks ├── debug │ └── LibraryName.xcframework └── release └── LibraryName.xcframework XCFramework
  55. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/prof18/hn-foundation-cocoa-xcframework

    CocoaPod Repository
  56. ADI x GDG Pisa - Android Days - @marcoGomier iOs

    Project: Podfile # For stable releases pod 'HNFoundation', :git => “git@github.com:prof18/hn-foundation-cocoa-xcframework.git", :tag => ‘2.0.0'
  57. register("publishFramework") { description = "Publish iOs framework to the Cocoa

    Repo" doFirst { project.exec { workingDir = File("$rootDir/ .. / .. /hn-foundation-cocoa-xcframework") commandLine("git", "checkout", "main").standardOutput } } dependsOn("assemble${libName}ReleaseXCFramework") doLast { copy { from("$buildDir/XCFrameworks/release") into("$rootDir/ .. / .. /hn-foundation-cocoa-xcframework") } .. .. https://github.com/prof18/shared-hn-android-ios-backend/blob/main/hn-foundation/build.gradle.kts#L177 Publish Release XCFramework Task
  58. ADI x GDG Pisa - Android Days - @marcoGomier

  59. ADI x GDG Pisa - Android Days - @marcoGomier https:

    // www.marcogomiero.com/posts/2021/kmp-xcframework-official-support/
  60. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/prof18/shared-hn-android-ios-backend

    * based on a true story project
  61. GDG Pisa - Android Days @marcoGomier How to start: new

    project
  62. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  63. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  64. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  65. GDG Pisa - Android Days @marcoGomier How to start: existing

    project
  66. ADI x GDG Pisa - Android Days - @marcoGomier Existing

    Projects: Intellij Wizard
  67. ADI x GDG Pisa - Android Days - @marcoGomier Photo

    by Erwan Hesry on Unsplash A little piece of tech stack to start with 💡 Create a library!
  68. ADI x GDG Pisa - Android Days - @marcoGomier •

    Boring code to write multiple times • Code/feature that centralises the source of truth (i.e. a field is nullable or not) • Code/feature that can be gradually extracted Where to start?
  69. ADI x GDG Pisa - Android Days - @marcoGomier •

    DTOs • Common Models • Utility methods, aka `object Utils {}` • Analytics • . . . Where to start?
  70. ADI x GDG Pisa - Android Days - @marcoGomier Start

    little
  71. ADI x GDG Pisa - Android Days - @marcoGomier Start

    little Go bigger then
  72. ADI x GDG Pisa - Android Days - @marcoGomier Start

    little then go bigger • Validate the process with “little” effort • Then you can go bigger and share more “features” 

  73. GDG Pisa - Android Days @marcoGomier Concurrency

  74. ADI x GDG Pisa - Android Days - @marcoGomier •

    Kotlin/Native different from the JVM • One thread -> no problems, you can use mutable objects • Many thread - > only immutable objects Concurrency https://kotlinlang.org/docs/mobile/concurrency-overview.html
  75. Uncaught Kotlin exception: kotlin.native.IncorrectDereferenceException: illegal attempt to access non-shared <object>@c2ddb8

    from other thread
  76. ADI x GDG Pisa - Android Days - @marcoGomier 🥶

    Freeze the object to share it between threads
  77. ADI x GDG Pisa - Android Days - @marcoGomier override

    fun deserialize(jsonString: String): NewsDTO { val newsDTO: NewsDTO = json.decodeFromString(jsonString) newsDTO.freeze() return newsDTO }
  78. ADI x GDG Pisa - Android Days - @marcoGomier https://blog.jetbrains.com/kotlin/2021/08/try-the-new-kotlin-native-memory-manager-development-preview/

  79. GDG Pisa - Android Days @marcoGomier Ecosystem

  80. ADI x GDG Pisa - Android Days - @marcoGomier •

    Networking: Ktor • Persistence: SQLDelight, multiplatform-settings • Serialization: kotlinx.serialization • Dependency Injection: koin, Kodein-DI • Reactive: Reaktive • Date/Time: kotlinx-datetime (still experimental) Common Libraries
  81. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/AAkira/Kotlin-Multiplatform-Libraries

  82. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/touchlab/xcode-kotlin

  83. ADI x GDG Pisa - Android Days - @marcoGomier

  84. ADI x GDG Pisa - Android Days - @marcoGomier Kotlin

    Multiplatform Mobile for AppCode https://blog.jetbrains.com/kotlin/2021/06/kmm-for-appcode/
  85. ADI x GDG Pisa - Android Days - @marcoGomier https://github.com/touchlab/CrashKiOS

  86. ADI x GDG Pisa - Android Days - @marcoGomier

  87. ADI x GDG Pisa - Android Days - @marcoGomier

  88. GDG Pisa - Android Days @marcoGomier Conclusions

  89. ADI x GDG Pisa - Android Days - @marcoGomier •

    Kotlin Multiplatform ! = Cross Platform • Alpha stage, Beta spring 2022 • It’s the future Conclusions
  90. Marco Gomiero ADI x GDG Pisa - Android Days Thank

    you! > Twitter: @marcoGomier 
 > Github: prof18 
 > Website: marcogomiero.com