Slide 1

Slide 1 text

Photo by FarawayPictures on deviantART @cafonsomota IT JUST WORKS* (*RUNNING COMPOSE ON ANDROID, DESKTOP, AND THE WEB ALONG WITH KMP)

Slide 2

Slide 2 text

šŸ‘ØšŸ’» Android GDE šŸ—£ Founder @GDGCoimbra and co-founder @Kotlin_Knights āœ Author @rwenderlich šŸ—ŗ Loves travel, photography and running šŸ» Looking to taste a Moretti with all of you @cafonsomota

Slide 3

Slide 3 text

šŸ–„ Slides speakerdeck.com/cmota/it-just-works šŸ‘‰ Code github.com/cmota/alicerce github.com/cmota/unsplash šŸæ YouTube bit.ly/cmota-youtube Materials @cafonsomota

Slide 4

Slide 4 text

A Brief history of Time

Slide 5

Slide 5 text

2008 2012 2018 2013 2011 2017 2006 2010 2009 2015 * Kotlin Multiplatform * @cafonsomota Mobile

Slide 6

Slide 6 text

1996 2006 2018 2013 2017 1995 * * Kotlin Multiplatform Desktop 2008 @cafonsomota

Slide 7

Slide 7 text

2012 2018 2014 2017 2006 2010 2009 2015 * * Kotlin Multiplatform Web @cafonsomota

Slide 8

Slide 8 text

myths of native, hybrid, and cross platform solutions

Slide 9

Slide 9 text

droiders šŸ¤– @cafonsomota

Slide 10

Slide 10 text

I’ve got a new app idea! droiders šŸ¤– @cafonsomota

Slide 11

Slide 11 text

Great!! Are you going to do it natively? I’ve got a new app idea! droiders šŸ¤– šŸ“± @cafonsomota

Slide 12

Slide 12 text

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 @cafonsomota

Slide 13

Slide 13 text

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! @cafonsomota

Slide 14

Slide 14 text

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! @cafonsomota

Slide 15

Slide 15 text

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! @cafonsomota

Slide 16

Slide 16 text

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 @cafonsomota

Slide 17

Slide 17 text

How to develop an application?

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

How to develop an application? Spoilers

Slide 21

Slide 21 text

How to develop an application?

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

Kotlin Multiplatform

Slide 24

Slide 24 text

Kotlin Multiplatform shares your business logic @cafonsomota

Slide 25

Slide 25 text

presentation presentation presentation presentation model model model model parser parser parser parser view network view network view network view network desktop web iOS android @cafonsomota

Slide 26

Slide 26 text

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

Slide 27

Slide 27 text

android iOS desktop model parser network presentation common view view view view java/kotlin objective-c/ swift (kotlin) JS supported in jvm web @cafonsomota

Slide 28

Slide 28 text

Kotlin Multiplatform: Platform Specific Code src/commonMain/sample/Platform.kt expect object Platform { val name: String } :shared @cafonsomota

Slide 29

Slide 29 text

src/commonMain/sample/Platform.kt 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 :shared @cafonsomota

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

src/commonMain/sample/Platform.kt :shared 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 @cafonsomota

Slide 33

Slide 33 text

*.kt common expect JVM actual *.kt, *.java, *.jar Native *.kt, *C, Swift, Framework JS *.kt, *.js, NPM actual actual

Slide 34

Slide 34 text

How to develop an application?

Slide 35

Slide 35 text

Compose

Slide 36

Slide 36 text

developer.android.com/jetpack/compose

Slide 37

Slide 37 text

Compose

Slide 38

Slide 38 text

šŸ¤” Compose

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

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

Slide 42

Slide 42 text

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

Slide 43

Slide 43 text

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

Slide 44

Slide 44 text

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

Slide 45

Slide 45 text

Compose UI Raspberry pi Compose Compiler Compose Runtime Compose UI Android Compose UI Desktop Compose UI Web Compose UI Console Compose

Slide 46

Slide 46 text

blog.jetbrains.com/kotlin/2021/10/compose-multiplatform-goes-beta/

Slide 47

Slide 47 text

Android, desktop, and Web

Slide 48

Slide 48 text

@cafonsomota :androidApp

Slide 49

Slide 49 text

:androidWearApp

Slide 50

Slide 50 text

@cafonsomota :desktopApp

Slide 51

Slide 51 text

:webApp

Slide 52

Slide 52 text

Now that we’ve got the android app ready, How quickly can we have desktop and web apps? - all the dreamers out there

Slide 53

Slide 53 text

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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

KOtlin Multiplatform: Targets jvm JS android android 
 NDK iOS watchOS tvOS macOS Linux Windows Web Assembly @cafonsomota

Slide 60

Slide 60 text

KOtlin Multiplatform: Libraries 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 @cafonsomota

Slide 61

Slide 61 text

How to Start?

Slide 62

Slide 62 text

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 :shared @cafonsomota

Slide 63

Slide 63 text

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

Slide 64

Slide 64 text

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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

androidApp/ desktopApp/ webApp/ shared/ KOtlin Multiplatform: Project Structure your platform speci fi c code (engine, drivers, etc.) :shared androidMain/ commonMain/ desktopMain/ jsMain/ @cafonsomota

Slide 71

Slide 71 text

KOtlin Multiplatform: Adding new Targets kotlin {a android() iOS()1 }b shared/build.gradle.kts :shared

Slide 72

Slide 72 text

shared/build.gradle.kts KOtlin Multiplatform: Adding new Targets kotlin {a android() jvm("desktop") js(IR) {c browser() binaries.executable() }d }b :shared

Slide 73

Slide 73 text

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

Slide 74

Slide 74 text

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

Slide 75

Slide 75 text

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

Slide 76

Slide 76 text

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

Slide 77

Slide 77 text

Do I need to refactor The entire Project?

Slide 78

Slide 78 text

Do I need to refactor The entire Project? NO

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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? @cafonsomota

Slide 81

Slide 81 text

What ā€˜challenges’ will you find?

Slide 82

Slide 82 text

KOtlin Multiplatform: ā€˜Challenges’ 🟔 Not all libraries are available on KMP Those who are might not support all targets They might not be compatible with your Kotlin version @cafonsomota

Slide 83

Slide 83 text

KOtlin Multiplatform: ā€˜Challenges’ 🟔 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 @cafonsomota

Slide 84

Slide 84 text

KOtlin Multiplatform: ā€˜Challenges’ 🟔 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 @cafonsomota

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

How to Start?

Slide 87

Slide 87 text

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 @cafonsomota

Slide 88

Slide 88 text

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 @cafonsomota

Slide 89

Slide 89 text

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 šŸ™‚ @cafonsomota

Slide 90

Slide 90 text

Compose Compose for Android androidx.compose @cafonsomota

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

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

Slide 93

Slide 93 text

Compose src/shared-ui/build.gradle.kts :shared-ui plugins { kotlin("multiplatform") id("org.jetbrains.compose") version ā€œ1.0.0-beta5" 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) } } } }

Slide 94

Slide 94 text

Compose šŸ’„ Duplicated class androidx.compose.* ... BUILD FAILED @cafonsomota

Slide 95

Slide 95 text

Compose You’re using two di ff erent versions of Compose androidx.compose org.jetbrains.compose @cafonsomota

Slide 96

Slide 96 text

Compose src/androidApp/build.gradle.kts :androidApp plugins { id("org.jetbrains.compose") version ā€œ1.0.0-beta5" id("com.android.application") kotlin("android") }

Slide 97

Slide 97 text

Do I need to refactor The entire Project?

Slide 98

Slide 98 text

Do I need to refactor The entire Project? NO

Slide 99

Slide 99 text

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 @cafonsomota

Slide 100

Slide 100 text

What ā€˜challenges’ will you find?

Slide 101

Slide 101 text

Compose: ā€˜Challenges’ 🟠 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 @cafonsomota

Slide 102

Slide 102 text

Compose: ā€˜Challenges’ 🟠 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 @cafonsomota

Slide 103

Slide 103 text

Compose: ā€˜Challenges’ 🟠 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 @cafonsomota

Slide 104

Slide 104 text

Compose: ā€˜Challenges’ šŸ”“ 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 @cafonsomota

Slide 105

Slide 105 text

How to Solve them

Slide 106

Slide 106 text

Compose: ā€˜Challenges’ 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 @cafonsomota

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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’

Slide 109

Slide 109 text

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! šŸš€

Slide 110

Slide 110 text

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

Slide 111

Slide 111 text

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’

Slide 112

Slide 112 text

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? 😭

Slide 113

Slide 113 text

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’

Slide 114

Slide 114 text

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

Slide 115

Slide 115 text

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’

Slide 116

Slide 116 text

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’

Slide 117

Slide 117 text

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’

Slide 118

Slide 118 text

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’

Slide 119

Slide 119 text

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

Slide 120

Slide 120 text

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

Slide 121

Slide 121 text

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?

Slide 122

Slide 122 text

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! šŸš€

Slide 123

Slide 123 text

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

Slide 124

Slide 124 text

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

Slide 125

Slide 125 text

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

Slide 126

Slide 126 text

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

Slide 127

Slide 127 text

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

Slide 128

Slide 128 text

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) )

Slide 129

Slide 129 text

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

Slide 130

Slide 130 text

@Composable public expect fun icAbout(): Painter @Composable public expect fun icHome(): Painter Resources: Images shared-ui/commonMain/Icons.kt Compose: Resources

Slide 131

Slide 131 text

@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

Slide 132

Slide 132 text

@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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 text

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

Slide 135

Slide 135 text

Compose: Resources Resources Imagine that you want to set a custom font Hello world! Text( text = ā€œHello World!ā€, style = typography.h4 ) Hello world!

Slide 136

Slide 136 text

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!

Slide 137

Slide 137 text

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

Slide 138

Slide 138 text

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

Slide 139

Slide 139 text

@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

Slide 140

Slide 140 text

@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

Slide 141

Slide 141 text

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

Slide 142

Slide 142 text

Compose: WebApp What about Web? @cafonsomota

Slide 143

Slide 143 text

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

Slide 144

Slide 144 text

Compose: WebApp Div({ style { position(Position.Relative) width(100.percent) height(400.px) flexGrow(1.0) marginBottom(10.px) } }) { Image(resource = image) } :webApp

Slide 145

Slide 145 text

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

Slide 146

Slide 146 text

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

Slide 147

Slide 147 text

Getting everything together

Slide 148

Slide 148 text

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

Slide 149

Slide 149 text

Resources

Slide 150

Slide 150 text

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 @cafonsomota

Slide 151

Slide 151 text

There’s one more thing?

Slide 152

Slide 152 text

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

Slide 153

Slide 153 text

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

Slide 154

Slide 154 text

Kotlin Multiplatform and Compose template Alicerce In Portuguese alicerce means foundation A Kotlin Multiplatform with Compose template Currently supports: Android and Desktop Contains an initial project con fi guration along with the libraries mentioned here Open to feedback and contributions! Alicerce

Slide 155

Slide 155 text

Photo by FarawayPictures on deviantART @cafonsomota IT JUST WORKS* (*RUNNING COMPOSE ON ANDROID, DESKTOP, AND THE WEB ALONG WITH KMP)