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

An Android, a Desktop, and a Web developer enter in a bar

D8a3623b157508fecdae1f8e756f362f?s=47 cmota
October 07, 2021

An Android, a Desktop, and a Web developer enter in a bar

Three different platforms meet at a bar and decided to share (pun intended) a couple of drinks.

This last year has been great for multiplatform development. As Kotlin keeps pushing for new releases and KMP starts to gain more adoption and stable releases, we now have the chance to write the UI for our Android apps with Compose and share it along with the Desktop and the Web.

In this talk, you’re going to see how you can start to decompose your Android app and start sharing all of its content along with a Desktop app and the Web. Drink at your own responsibility.

D8a3623b157508fecdae1f8e756f362f?s=128

cmota

October 07, 2021
Tweet

More Decks by cmota

Other Decks in Technology

Transcript

  1. @cafonsomota An Android, A Desktop, and A Web Developer enter

    in a Bar Photo by Alexander Popov on Unsplash
  2. Photo by Alexander Popov on Unsplash An Android, A Desktop,

    and A Web Developer enter in a Bar *following all the public health measures @cafonsomota
  3. hello mobiconf! 👋 @cafonsomota

  4. 👨💻 Android GDE 🗣 Founder @GDGCoimbra and co-founder @Kotlin_Knights ✍

    Author @rwenderlich 🗺 Loves travel, photography and running 🍻 Looking to taste a Zywiec Biale with all of you hello mobiconf! 👋 @cafonsomota
  5. 🖥 Slides speakerdeck.com/cmota/an-android-a-desktop-and-a-web-developer-enter-in-a-bar 👉 Code github.com/cmota/alicerce github.com/cmota/unsplash 🍿 YouTube bit.ly/cmota-youtube

    Materials @cafonsomota
  6. 💬 How we built a Jetpack Compose Chat SDK, by

    Filip Babić 📱 KMP for Mobile Developers, by Enrique López Mañas Mobiconf talks @cafonsomota
  7. A Brief history of Time

  8. 2008 2012 2018 2013 2011 2017 2006 2010 2009 2015

    * Kotlin Multiplatform * @cafonsomota Mobile
  9. 1996 2006 2018 2013 2017 1995 * @cafonsomota * Kotlin

    Multiplatform Desktop 2008
  10. 2008 2012 2018 2014 2017 2006 2010 2009 2015 *

    @cafonsomota * Kotlin Multiplatform Web
  11. myths of native, hybrid, and cross platform solutions

  12. @cafonsomota droiders 🤖

  13. @cafonsomota I’ve got a new app idea! droiders 🤖

  14. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱
  15. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱 Natively? You can use Xamarin and instead of android only, you get android and iOS
  16. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱 Natively? You can use Xamarin and instead of android only, you get android and iOS For that, you should use Flutter! It has better performance!
  17. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱 Natively? You can use Xamarin and instead of android only, you get android and iOS For that, you should use Flutter! It has better performance! But it uses Dart! You’re already familiar with Kotlin, you should try Kotlin Multiplatform!
  18. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱 Natively? You can use Xamarin and instead of android only, you get android and iOS For that, you should use Flutter! It has better performance! But it uses Dart! You’re already familiar with Kotlin, you should try Kotlin Multiplatform! I’ve been using react native and it’s great!
  19. @cafonsomota Great!! Are you going to do it natively? I’ve

    got a new app idea! droiders 🤖 📱 Natively? You can use Xamarin and instead of android only, you get android and iOS For that, you should use Flutter! It has better performance! But it uses Dart! You’re already familiar with Kotlin, you should try Kotlin Multiplatform! I’ve been using react native and it’s great! 12 people are typing
  20. How to develop an application?

  21. How to decide? Team background and size Which language is

    your team familiar with? Do they want to learn new things? Can you have developers focused on each platform you’re targeting? Project type Are you developing an MVP? 1yr long project? 5yr? Never ending project? Constraints Time: It hasn’t started yet, and you’re already behind schedule? Budget: Can you hire/allocate more people? @cafonsomota
  22. Framework dependent OS updates require the fw to be updated

    and launch a new app Missing features OS/device features depend on the fw support, you might need to write them Slower performance Commitment to one framework Common disadvantages @cafonsomota
  23. How to develop an application? Spoilers

  24. How to develop an application?

  25. It’s Kotlin ❤ Take advantage of all the language features

    (that you’re already familiar with) Low risk Decide what’s worth to share across platforms Consistency across platforms One tech-stack Strong community support KOtlin Multiplatform @cafonsomota
  26. Kotlin Multiplatform

  27. @cafonsomota Kotlin Multiplatform shares your business logic

  28. presentation model parser view network presentation model parser view network

    presentation model parser view network presentation model parser view network desktop web iOS android @cafonsomota
  29. business logic business logic business logic model parser network presentation

    model parser network presentation model parser network presentation model parser network presentation business logic view view view view desktop web iOS android @cafonsomota
  30. android iOS desktop model parser network presentation common view view

    view view java/kotlin objective-c/ swift (kotlin) JS supported in jvm web @cafonsomota
  31. Kotlin Multiplatform: Platform Specific Code src/commonMain/sample/Platform.kt :shared @cafonsomota expect object

    Platform { val name: String }
  32. src/commonMain/sample/Platform.kt :shared @cafonsomota expect object Platform { val name: String

    } You need to de fi ne actual per target actual for Android actual for Desktop actual for JS Kotlin Multiplatform: Platform Specific Code
  33. src/commonMain/sample/Platform.kt :shared @cafonsomota expect object Platform { val name: String

    } src/androidMain/sample/Platform.kt actual object Platform { actual val name: String = "android" } Kotlin Multiplatform: Platform Specific Code
  34. src/commonMain/sample/Platform.kt :shared @cafonsomota expect object Platform { val name: String

    } src/androidMain/sample/Platform.kt actual object Platform { actual val name: String = “android” } Kotlin Multiplatform: Platform Specific Code
  35. src/commonMain/sample/Platform.kt :shared @cafonsomota expect object Platform { val name: String

    } src/androidMain/sample/Platform.kt src/desktopMain/sample/Platform.kt src/webMain/sample/Platform.kt actual object Platform { actual val name: String = “android” } actual object Platform { actual val name: String = “desktop” } actual object Platform { actual val name: String = “web” } Kotlin Multiplatform: Platform Specific Code
  36. *.kt common expect JVM actual *.kt, *.java, *.jar Native *.kt,

    *C, Swift, Framework JS *.kt, *.js, NPM actual actual
  37. How to develop an application?

  38. Compose

  39. developer.android.com/jetpack/compose

  40. Compose

  41. 🤔 Compose

  42. Jetpack Compose compose.animation compose.material compose.foundation compose.ui compose.runtime compose.compiler

  43. Jetpack Compose compose.animation compose.material compose.foundation compose.ui compose.runtime compose.compiler Compose Compiler

    Compose Runtime Compose UI Toolkit (Android) Compose Animation Compose UI Compose Foundation Compose Material
  44. Jetpack Compose compose.animation compose.material compose.foundation compose.ui compose.runtime compose.compiler Compose Compiler

    Compose Runtime Compose UI Toolkit (Android) Compose Animation Compose UI Compose Foundation Compose Material
  45. Compose Compiler Compose Runtime Compose UI Toolkit (Android) Compose Animation

    Compose UI Compose Foundation Compose Material Compose compiler android.googlesource.com/platform/frameworks/support/+/HEAD/compose/compiler Written in Kotlin Transforms @Composable into UI Doesn’t use the Annotation Processor The plugin works at system/code generation level Doesn’t impact build times Open source Available in the AOSP
  46. Compose Runtime Platform agnostic Doesn’t know what Android or UI

    are Tree management solution Compose Compiler Compose Runtime Compose UI Toolkit (Android) Compose Animation Compose UI Compose Foundation Compose Material
  47. Compose UI Toolkit Compose Compiler Compose Runtime Compose UI Toolkit

    (Android) Compose Animation Compose UI Compose Foundation Compose Material compose.ui Handles input management, Drawing, Layouts, etc. compose.foundation Contains Basic building: Column, Text, Image, etc. compose.material Material design system to use on components compose.animation Animations to use easily and out side of the box
  48. Compose UI Raspberry pi Compose Compiler Compose Runtime Compose UI

    Android Compose UI Desktop Compose UI Web Compose UI Console Compose
  49. blog.jetbrains.com/kotlin/2021/08/compose-multiplatform-goes-alpha/

  50. Android, desktop, and Web

  51. @cafonsomota :androidApp

  52. :desktopApp

  53. :webApp

  54. Now that we’ve got the android app ready, How quickly

    can we have desktop and web apps? - all the dreamers out there
  55. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge!
  56. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge! 👉
  57. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge! 👉
  58. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge! 👉
  59. @cafonsomota Kotlin Multiplatform shares your business logic Compose shares your

    (native) UI
  60. @cafonsomota Kotlin Multiplatform shares your business logic Compose shares your

    (native) UI
  61. KOtlin Multiplatform: Targets @cafonsomota jvm JS android android 
 NDK

    iOS watchOS tvOS macOS Linux Windows Web Assembly
  62. KOtlin Multiplatform: Libraries @cafonsomota Kotlinx.x Coroutines, serialization, datetime, atomicfu, etc.

    Network Ktor: github.com/ktorio/ktor Storage Database: github.com/cashapp/sqldelight Others Curated list: github.com/AAkira/Kotlin-Multiplatform-Libraries
  63. How to Start?

  64. @cafonsomota KOtlin Multiplatform: Creating a new KMM project 1. Install

    the KMM plugin on Android Studio 2. Create a new KMM Application ⚠ There’s a version that supports Mac M1 :shared
  65. @cafonsomota KOtlin Multiplatform: Project Structure androidApp/ iosApp/ shared/ :shared

  66. @cafonsomota KOtlin Multiplatform: Project Structure androidApp/ iosApp/ shared/ :shared

  67. @cafonsomota KOtlin Multiplatform: Project Structure androidApp/ iosApp/ shared/ :shared

  68. @cafonsomota KOtlin Multiplatform: Project Structure androidApp/ desktopApp/ webApp/ shared/ :shared

  69. @cafonsomota KOtlin Multiplatform: Project Structure androidApp/ desktopApp/ webApp/ shared/ :shared

  70. androidApp/ desktopApp/ webApp/ shared/ @cafonsomota KOtlin Multiplatform: Project Structure :shared

    androidMain/ commonMain/ iosMain/
  71. androidApp/ desktopApp/ webApp/ shared/ @cafonsomota KOtlin Multiplatform: Project Structure your

    common code (logic) androidMain/ commonMain/ desktopMain/ jsMain/ :shared
  72. androidApp/ desktopApp/ webApp/ shared/ @cafonsomota KOtlin Multiplatform: Project Structure your

    platform speci fi c code (engine, drivers, etc.) :shared androidMain/ commonMain/ desktopMain/ jsMain/
  73. KOtlin Multiplatform: Adding new Targets kotlin {a android() iOS()1 }b

    shared/build.gradle.kts :shared
  74. shared/build.gradle.kts KOtlin Multiplatform: Adding new Targets kotlin {a android() jvm("desktop")

    js(IR) {c browser() binaries.executable() }d }b :shared
  75. shared/build.gradle.kts KOtlin Multiplatform: Refactoring to KMP kotlin { ... sourceSets

    { val commonMain by getting dependencies implementation(“io.ktor:ktor-client-core:1.6.4") val androidMain by getting dependencies implementation("io.ktor:ktor-client-android:1.6.4") val desktopMain by getting val jsMain by getting dependencies implementation("io.ktor:ktor-client-js:1.6.4") } } Network ✅ Migrating to Ktor :shared
  76. shared/build.gradle.kts ✅ Migrating to SQLDelight KOtlin Multiplatform: Refactoring to KMP

    kotlin { ... sourceSets { val commonMain by getting val androidMain by getting dependencies implementation("com.squareup.sqldelight:android-driver:1.5.1") val desktopMain by getting dependencies implementation("com.squareup.sqldelight:native-driver:1.5.1") val jsMain by getting dependencies implementation("com.squareup.sqldelight:sqljs-driver:1.5.1") } } :shared
  77. kotlin { ... sourceSets { val commonMain by getting dependencies

    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0") val androidMain by getting val desktopMain by getting val jsMain by getting } } shared/build.gradle.kts ✅ Migrating to kotlinx.serialization KOtlin Multiplatform: Refactoring to KMP :shared
  78. kotlin { ... sourceSets { val commonMain by getting dependencies

    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.0") val androidMain by getting val desktopMain by getting val jsMain by getting } } shared/build.gradle.kts ✅ Migrating to kotlinx.serialization KOtlin Multiplatform: Refactoring to KMP shared module And of course, Also migratE the API Calls
  79. Do I need to refactor The entire Project?

  80. Do I need to refactor The entire Project? NO

  81. KOtlin Multiplatform You don’t need to commit your entire codebase

    to KMP The goal is to share your business logic Di ff erent apps share di ff erent parts of their code - what makes sense to them! Space *Adapted from: KotlinConf 2019: Opening Keynote by Andrey Breslav Full KMP Cash App Shares: business logic Yandex Maps Shares: business logic, wrappers for C++ libraries PlanGrid Planboard Workspace Shares: business logic, sync logic, mgmnt o ffl ine data Shares: business logic Shares: business logic, networking, o ffl ine caching lyrs
  82. @cafonsomota KOtlin Multiplatform: ‘Suggestions’ Start small You’re going to develop

    a new feature? There’s part of your app that needs to be refactored? Want to improve your test coverage? why not do it on the shared module?
  83. What ‘challenges’ will you find?

  84. KOtlin Multiplatform: ‘Challenges’ @cafonsomota 🟡 Not all libraries are available

    on KMP Those who are might not support all targets They might not be compatible with your Kotlin version
  85. KOtlin Multiplatform: ‘Challenges’ @cafonsomota 🟡 Not all libraries are available

    for KMP Those who are might not support all targets They might not be compatible with your Kotlin version 🟠 Project initial setup requires some time Invalidate cache and restart is needed sometimes to recover code auto-complete There are properties that you need to con fi gure: export (iOS), @JsName (JS), etc. Especially when targeting Web, you should enable the IR compiler
  86. KOtlin Multiplatform: ‘Challenges’ @cafonsomota 🟡 Not all libraries are available

    for KMP Those who are might not support all targets They might not be compatible with your Kotlin version 🟠 Project initial setup requires some time Invalidate cache and restart is needed sometimes to recover code auto-complete There are properties that you need to con fi gure: export (iOS), @JsName (JS), etc. Especially when targeting Web, you should enable the IR compiler 🔴 Generated library might need to lose some weight Especially when targeting Web, they can easily gain several MB’s
  87. @cafonsomota Kotlin Multiplatform shares your business logic Compose shares your

    (native) UI
  88. How to Start?

  89. @cafonsomota Compose: Getting Ready If you’re starting Compose for the

    fi rst time Start by developing fi rst on Android Once done, you can move it to a shared module If you’re already familiar with it Create a shared-ui module that will de fi ne the UI for the di ff erent platforms
  90. @cafonsomota Compose: Getting Ready 1. Create a new module called

    shared-ui 2. You can just copy-paste shared Rename it to shared-ui Remove all of it’s .kt classes
  91. @cafonsomota Compose To share your Compose UI you’ll need to

    do a bit of KMP Di ff erent platforms, mean di ff erent behaviours For instance, you can resize a window on the desktop but not on your phone* You have di ff erent input types, etc. * well, you can have the app in split screen mode, yes 🙂
  92. @cafonsomota Compose: Project Structure androidApp/ desktopApp/ webApp/ shared/ Unsplash

  93. @cafonsomota androidApp/ desktopApp/ webApp/ shared/ shared-ui/ :shared-ui Compose: Project Structure

  94. @cafonsomota androidApp/ desktopApp/ webApp/ shared/ shared-ui/ :shared-ui androidMain/ commonMain/ desktopMain/

    Compose: Project Structure
  95. @cafonsomota Compose Compose for Android androidx.compose

  96. @cafonsomota Compose Compose for Android androidx.compose Compose for Desktop/Web org.jetbrains.compose

  97. Compose src/shared-ui/build.gradle.kts :shared-ui plugins { kotlin("multiplatform") id("org.jetbrains.compose") version "1.0.0-alpha3" id("com.android.library")

    kotlin("plugin.serialization") }
  98. Compose src/shared-ui/build.gradle.kts :shared-ui plugins { kotlin("multiplatform") id("org.jetbrains.compose") version "1.0.0-alpha3" id("com.android.library")

    kotlin("plugin.serialization") } kotlin { ... sourceSets { val commonMain by getting { dependencies { api(compose.foundation) api(compose.runtime) api(compose.foundation) api(compose.material) api(compose.materialIconsExtended) api(compose.ui) api(compose.uiTooling) } } } }
  99. @cafonsomota Compose 💥 Duplicated class androidx.compose.* ... BUILD FAILED

  100. @cafonsomota Compose You’re using two di ff erent versions of

    Compose androidx.compose org.jetbrains.compose
  101. Compose src/androidApp/build.gradle.kts :androidApp plugins { id("org.jetbrains.compose") version "1.0.0-alpha3" id("com.android.application") kotlin("android")

    }
  102. Do I need to refactor The entire Project?

  103. Do I need to refactor The entire Project? NO

  104. Compose Compose is interoperable with XML You don’t need to

    rewrite your entire app with Compose You’ll only be able to share the features that are using Compose
  105. What ‘challenges’ will you find?

  106. Compose: ‘Challenges’ @cafonsomota 🟠 Initial setup is… challenging You’ll need

    to use JetBrains Compose plugin Adding the wrong con fi guration might increase building times in several minutes
  107. Compose: ‘Challenges’ @cafonsomota 🟠 Initial setup is… challenging You’ll need

    to use JetBrains Compose plugin Adding the wrong con fi guration might increase building times in several minutes 🟠 Libraries depend on the Compose version You’ll need to use a compatible one
  108. Compose: ‘Challenges’ @cafonsomota 🟠 Initial setup is… challenging You’ll need

    to use JetBrains Compose plugin Adding the wrong con fi guration might increase building times in several minutes 🟠 Libraries depend on the Compose version You’ll need to use a compatible one 🟠 Not all features are available for Desktop/ Web There’s no direct support for i18n, fonts and other resources LiveData, ViewModels, etc. are only available through third-party libraries
  109. Compose: ‘Challenges’ @cafonsomota 🔴 Web… is in it’s initial stages

    Not all Compose functions are ported to the Web The ones that are, often require that you use DOM elements to manipulate them Adding this abstraction manually will be really time consuming
  110. How to Solve them

  111. Compose: ‘Challenges’ @cafonsomota Accompanist A set of libraries that provide

    Compose ready features Examples: Insets, Paging, Permissions, Swipe to refresh, etc. 📐 Insets 🍫 System UI Controller 🎨 AppCompat Theme Adapter 🧭✨Navigation-Animation 📫 Permissions ⏳ Placeholder 🌊 Flow Layouts 🧭🎨 Navigation-Material 🖌 Drawable Painter ⬇ Swipe to Refresh 📖 Pager
  112. Accompanist A set of libraries that provide Compose ready features

    Examples: Insets, Paging, Permissions, Swipe to refresh, etc. Compose: ‘Challenges’
  113. Accompanist A set of libraries that provide Compose ready features

    Examples: Insets, Paging, Permissions, Swipe to refresh, etc. Not all Compose libraries are supported on Desktop and Web… for now! Compose: ‘Challenges’
  114. Compose: ‘Challenges’ Accompanist A set of libraries that provide Compose

    ready features Examples: Insets, Paging, Permissions, Swipe to refresh, etc. Not all Compose libraries are supported on Desktop and Web… for now! Community to the rescue! 🚀
  115. Accompanist (by Syer10) A subset of accompanist libraries ported by

    Syer10 to Desktop Available at: syer10.github.io/accompanist Compose: ‘Challenges’
  116. Accompanist (by Syer10) A subset of accompanist libraries ported by

    Syer10 to Desktop Available at: syer10.github.io/accompanist ⚠ only works on Desktop Compose: ‘Challenges’
  117. Compose: ‘Challenges’ Accompanist (by Syer10) A subset of accompanist libraries

    ported by Syer10 to Desktop Available at: syer10.github.io/accompanist ⚠ only works on Desktop Why? 😭
  118. plugins { kotlin("multiplatform") id("org.jetbrains.compose") version "1.0.0-alpha3" } kotlin { api(compose.material)

    api(compose.ui) } Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’
  119. plugins { kotlin("multiplatform") id("org.jetbrains.compose") version "1.0.0-alpha3" } kotlin { api(compose.material)

    api(compose.ui) } Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’ ⚠ Not exported to Android
  120. plugins {1 kotlin("multiplatform") id("org.jetbrains.compose") version “1.0.0-alpha3" id("com.android.library") }2 kotlin {a

    api(compose.material) api(compose.ui) }b Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’
  121. plugins {1 kotlin("multiplatform") id("org.jetbrains.compose") version “1.0.0-alpha3" id("com.android.library") }2 kotlin {a

    android {b publishLibraryVariants("release", “debug") }c jvm(“desktop") }d Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’
  122. plugins {1 kotlin("multiplatform") id("org.jetbrains.compose") version “1.0.0-alpha3" id("com.android.library") }2 kotlin {a

    android {b publishLibraryVariants("release", “debug") }c jvm(“desktop”)e sourceSets {f val commonMain by getting {g dependencies {h api(compose.material) api(compose.ui) }i }j val androidMain by getting val desktopMain by getting }d Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’
  123. plugins {1 kotlin("multiplatform") id("org.jetbrains.compose") version “1.0.0-alpha3" id("com.android.library") }2 kotlin {a

    android {b publishLibraryVariants("release", “debug") }c jvm(“desktop”)e sourceSets {f val commonMain by getting {g dependencies {h api(compose.material) api(compose.ui) }i }j val androidMain by getting val desktopMain by getting }d android { compileSdk = 31 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { minSdk = 21 targetSdk = 31 } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’
  124. plugins { kotlin("multiplatform") id("org.jetbrains.compose") version “1.0.0-alpha3" id("com.android.library") } kotlin {

    android { publishLibraryVariants("release", “debug") } jvm(“desktop") sourceSets { val commonMain by getting { dependencies { api(compose.material) api(compose.ui) } } val androidMain by getting val desktopMain by getting } android { compileSdk = 31 sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml") defaultConfig { minSdk = 21 targetSdk = 31 } compileOptions { sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 } } Syer10 Accompanist Syer10/accompanist/build.gradle.kts Compose: ‘Challenges’ ✅ Supports Android and Desktop
  125. Compose: Image Loading Coil-Compose Image loading library implemented in Kotlin

    (and using Coroutines) @cafonsomota
  126. Compose: Image Loading Coil-Compose Image loading library implemented in Kotlin

    (and using Coroutines) Not all Compose libraries are supported on Desktop and Web… for now?
  127. Not all Compose libraries are supported on Desktop and Web…

    for now? Compose: Image Loading Coil-Compose Image loading library implemented in Kotlin (and using Coroutines) Community to the rescue! 🚀
  128. Compose: Image Loading Kamel Asynchronous media loading library for Android

    and Desktop Uses Ktor in the background Get it from: github.com/alialbaali/Kamel @cafonsomota
  129. Compose: Image Loading val request = ImageRequest.Builder(LocalContext.current) .data(url) .crossfade(true) .build()

    val painter = rememberImagePainter(request) when (val resource = lazyPainterResource(url)) { is ImagePainter.Loading -> { AddImagePreviewLoading(modifier) } is ImagePainter.Success -> { Image( painter = painter, contentScale = ContentScale.Crop, contentDescription = "Image preview", modifier = modifier) } is ImagePainter.Failure -> { AddImagePreviewFailure(modifier) } Coil
  130. Compose: Image Loading when (val resource = lazyPainterResource(url)) { is

    Resource.Loading -> { AddImagePreviewLoading(modifier) } is Resource.Success -> { KamelImage( resource = resource, contentScale = ContentScale.Crop, contentDescription = "Image preview", modifier = modifier, crossfade = true ) } is Resource.Failure -> { AddImagePreviewFailure(modifier) } Kamel
  131. Compose: Image Loading when (val resource = lazyPainterResource(url)) { is

    Resource.Loading -> { AddImagePreviewLoading(modifier) } is Resource.Success -> { KamelImage( resource = resource, contentScale = ContentScale.Crop, contentDescription = "Image preview", modifier = modifier, crossfade = true ) } is Resource.Failure -> { AddImagePreviewFailure(modifier) } Kamel ⚠ Last supported version is 1.0.0-alpha3 (Kamel version 0.2.2)
  132. Compose: Resources Resources Imagine that you want to show an

    image @cafonsomota
  133. Compose: Resources Resources Imagine that you want to show an

    image Hello world!
  134. Compose: Resources Resources Imagine that you want to show an

    image Hello world! Image( painter = painterResource(id = R.drawable.ic_launcher), contentDescription = stringResource(id = R.string.app_name) )
  135. Compose: Resources Resources Imagine that you want to show an

    image Implementation shared-ui/commonMain contains the expect implementation shared-ui/androidMain contains the xml fi les (vectors) and actual implementation shared-ui/desktopMain contains the images (png’s) and actual implementation @cafonsomota
  136. @Composable public expect fun icAbout(): Painter @Composable public expect fun

    icHome(): Painter Resources: Images shared-ui/commonMain/Icons.kt Compose: Resources
  137. @Composable public actual fun icAbout() = painterResource(R.drawable.ic_about) @Composable public actual

    fun icHome() = painterResource(R.drawable.ic_home) Resources: Images shared-ui/androidApp/Icons.kt Compose: Resources
  138. @Composable public actual fun icAbout() = painterResource("images/ic_about.png") @Composable public actual

    fun icHome() = painterResource("images/ic_home.png") Resources: Images shared-ui/desktopApp/Icons.kt Compose: Resources
  139. Compose: Resources Resources Imagine that you want to set a

    custom font @cafonsomota
  140. Compose: Resources Resources Imagine that you want to set a

    custom font Hello world! Hello world!
  141. Compose: Resources Resources Imagine that you want to set a

    custom font Hello world! Text( text = “Hello World!”, style = typography.h4 ) Hello world!
  142. Compose: Resources Resources Imagine that you want to set a

    custom font Hello world! private val HollywoodHillsFontFamily = FontFamily( Font(R.font.sf_hollywood_hills) ) h4 = TextStyle( color = colorAccent, fontFamily = HollywoodHillsFontFamily, fontSize = fontSizeLarge ) Hello world!
  143. Compose: Resources Resources Imagine that you want to set a

    custom font Implementation shared-ui/commonMain/resources contains the font fi les shared-ui/commonMain/platform de fi nes the expect function shared-ui/androidMain/platform de fi nes the actual function shared-ui/desktopMain/platform de fi nes the actual function @cafonsomota
  144. @Composable expect fun Font( name: String, res: String ): Font

    Resources: Font shared-ui/commonMain/platform/PlatformFont.kt Compose: Resources
  145. @Composable actual fun Font( name: String, res: String, ): Font

    { val context = LocalContext.current val id = context.resources.getIdentifier(res, "font", context.packageName) return Font(id) } Resources: Font shared-ui/androidMain/platform/PlatformFont.kt Compose: Resources
  146. @Composable actual fun Font( name: String, res: String ): Font

    { androidx.compose.ui.text.platform.Font("font/$res.ttf") } shared-ui/desktopMain/platform/PlatformFont.kt Resources: Font Compose: Resources
  147. Compose: Lifecycle, ViewModel, LiveData and Navigation PreCompose (by Tlaster) Lifecycle,

    ViewModel, LiveData and Navigation are Android components They now have been ported to Compose desktop Get it from: github.com/Tlaster/PreCompose
  148. Compose: WebApp What about Web? @cafonsomota

  149. Compose: WebApp What about Web? Is in an initial stage

    and the paradigm is di ff erent It’s focused on DOM rendering Only a set of components are available: Box, Button, Column, Row, Slider, Text @cafonsomota
  150. Compose: WebApp Div({ style { position(Position.Relative) width(100.percent) height(400.px) flexGrow(1.0) marginBottom(10.px)

    } }) { Image(resource = image) } :webApp
  151. Compose: WebApp @Composable fun Column(content: @Composable () -> Unit) {

    Div({ style { display(DisplayStyle.Flex) alignItems(AlignItems.Center) flexGrow(1.0) } }) { content() } } :webApp webApp/components/Column.kt
  152. Compose: WebApp Sharing logic Works without any issue The generated

    JS fi le might be up to several MBs Sharing UI It’s going to be time consuming to share everything You’re going to need to create several components Most of the libraries don’t support it (yet) Nevertheless… it’s fun to see how long we’ll be able to go in a couple of months! @cafonsomota
  153. Getting everything together

  154. Status 🟢 Kotlin Multiplatform Mobile is stable-ish Can be used

    in production although part of it is in alpha/beta 🟢 Compose (Android) is stable Go on! It’s time to dive-in into declarative UI 🟡 Compose (Desktop) is alpha-ish 🔴 Compose (Web) is alpha 🟠 Documentation and samples 🟢 Community and support @cafonsomota
  155. Resources

  156. Jetpack Compose samples (Google) github.com/android/compose-samples Jetpack Compose samples (JetBrains) https://github.com/JetBrains/compose-jb/

    Jetpack/JetBrains Compose Playground foso.github.io/Jetpack-Compose-Playground/ Jetpack Compose Internals Kotlin Slack Resources
  157. There’s one more thing?

  158. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge! 👉
  159. @cafonsomota SELECT YOUR LEVEL I just want to see the

    story. I want a lighter experience. Give me the full challenge! 👉
  160. Kotlin Multiplatform and Compose template Alicerce In Portuguese alicerce means

    foundation A Kotlin Multiplatform with Compose template Currently supports: Android, Desktop and Web Contains an initial project con fi guration along with the libraries mentioned here Open to feedback and contributions! Alicerce
  161. Photo by Hans Isaacson on Unsplash @cafonsomota An Android, A

    Desktop, and A Web Developer enter in a Bar