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

Hi, have you met Kotlin Multiplatform - ADI x G...

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.

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 “Classic”

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

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

    Native: call native widgets through a “bridge”
  6. 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
  7. 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
  8. 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
  9. 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
  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 Mobile & Desktop App + JVM Backend
  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 Full Stack JS App
  12. 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?
  13. ADI x GDG Pisa - Android Days - @marcoGomier Common

    expect fun debugLog(tag: String, message: String)
  14. 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) }
  15. 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) } }
  16. 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
  17. ADI x GDG Pisa - Android Days - @marcoGomier shared

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

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

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

    Projects: Android Studio plugin
  21. 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
  22. ADI x GDG Pisa - Android Days - @marcoGomier New

    Projects: Android Studio plugin
  23. 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
  24. ADI x GDG Pisa - Android Days - @marcoGomier iOS

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

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

    Name - @marcoGomier . └── kmm-project ├── androidApp ├── iosApp └── shared Same Repository
  27. ADI x GDG Pisa - Android Days - @marcoGomier Conference

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

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

    Kotlin Android App iOs App .aar Framework 
 Maven 
 Cocoa Repo
  30. 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
  31. 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
  32. ADI x GDG Pisa - Android Days - @marcoGomier Publish

    the artifacts ./gradlew publish ./gradlew publishToMavenLocal
  33. ADI x GDG Pisa - Android Days - @marcoGomier NEW

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

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

    prior to Kotlin 1.5.30 https: / / www.marcogomiero.com/posts/2021/build-xcframework-kmp/
  36. 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) } } ... }
  37. ADI x GDG Pisa - Android Days - @marcoGomier assemble${libName}XCFramework

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

    ├── build ├── XCFrameworks ├── debug │ └── LibraryName.xcframework └── release └── LibraryName.xcframework XCFramework
  39. ADI x GDG Pisa - Android Days - @marcoGomier iOs

    Project: Podfile # For stable releases pod 'HNFoundation', :git => “[email protected]:prof18/hn-foundation-cocoa-xcframework.git", :tag => ‘2.0.0'
  40. 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
  41. ADI x GDG Pisa - Android Days - @marcoGomier https:

    // www.marcogomiero.com/posts/2021/kmp-xcframework-official-support/
  42. ADI x GDG Pisa - Android Days - @marcoGomier New

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

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

    Projects: Android Studio plugin
  45. 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!
  46. 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?
  47. ADI x GDG Pisa - Android Days - @marcoGomier •

    DTOs • Common Models • Utility methods, aka `object Utils {}` • Analytics • . . . Where to start?
  48. 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” 

  49. 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
  50. ADI x GDG Pisa - Android Days - @marcoGomier 🥶

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

    fun deserialize(jsonString: String): NewsDTO { val newsDTO: NewsDTO = json.decodeFromString(jsonString) newsDTO.freeze() return newsDTO }
  52. 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
  53. ADI x GDG Pisa - Android Days - @marcoGomier Kotlin

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

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

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