Slide 1

Slide 1 text

@cafonsomota An Android, A Desktop, and A Web Developer enter in a Bar Photo by Alexander Popov on Unsplash

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

hello mobiconf! šŸ‘‹ @cafonsomota

Slide 4

Slide 4 text

šŸ‘ØšŸ’» 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

Slide 5

Slide 5 text

šŸ–„ 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

Slide 6

Slide 6 text

šŸ’¬ How we built a Jetpack Compose Chat SDK, by Filip Babić šŸ“± KMP for Mobile Developers, by Enrique LĆ³pez MaƱas Mobiconf talks @cafonsomota

Slide 7

Slide 7 text

A Brief history of Time

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

myths of native, hybrid, and cross platform solutions

Slide 12

Slide 12 text

@cafonsomota droiders šŸ¤–

Slide 13

Slide 13 text

@cafonsomota Iā€™ve got a new app idea! droiders šŸ¤–

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

@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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

@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

Slide 20

Slide 20 text

How to develop an application?

Slide 21

Slide 21 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 22

Slide 22 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 23

Slide 23 text

How to develop an application? Spoilers

Slide 24

Slide 24 text

How to develop an application?

Slide 25

Slide 25 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 26

Slide 26 text

Kotlin Multiplatform

Slide 27

Slide 27 text

@cafonsomota Kotlin Multiplatform shares your business logic

Slide 28

Slide 28 text

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

Slide 29

Slide 29 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 30

Slide 30 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 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

How to develop an application?

Slide 38

Slide 38 text

Compose

Slide 39

Slide 39 text

developer.android.com/jetpack/compose

Slide 40

Slide 40 text

Compose

Slide 41

Slide 41 text

šŸ¤” Compose

Slide 42

Slide 42 text

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

Slide 43

Slide 43 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 44

Slide 44 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 45

Slide 45 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 46

Slide 46 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 47

Slide 47 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 48

Slide 48 text

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

Slide 49

Slide 49 text

blog.jetbrains.com/kotlin/2021/08/compose-multiplatform-goes-alpha/

Slide 50

Slide 50 text

Android, desktop, and Web

Slide 51

Slide 51 text

@cafonsomota :androidApp

Slide 52

Slide 52 text

:desktopApp

Slide 53

Slide 53 text

:webApp

Slide 54

Slide 54 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 55

Slide 55 text

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

Slide 56

Slide 56 text

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

Slide 57

Slide 57 text

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

Slide 58

Slide 58 text

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

Slide 59

Slide 59 text

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

Slide 60

Slide 60 text

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

Slide 61

Slide 61 text

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

Slide 62

Slide 62 text

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

Slide 63

Slide 63 text

How to Start?

Slide 64

Slide 64 text

@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

Slide 65

Slide 65 text

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

Slide 66

Slide 66 text

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

Slide 67

Slide 67 text

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

Slide 68

Slide 68 text

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

Slide 69

Slide 69 text

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

Slide 70

Slide 70 text

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

Slide 71

Slide 71 text

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

Slide 72

Slide 72 text

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

Slide 73

Slide 73 text

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

Slide 74

Slide 74 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 75

Slide 75 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 76

Slide 76 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 77

Slide 77 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 78

Slide 78 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 79

Slide 79 text

Do I need to refactor The entire Project?

Slide 80

Slide 80 text

Do I need to refactor The entire Project? NO

Slide 81

Slide 81 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 82

Slide 82 text

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

Slide 83

Slide 83 text

What ā€˜challengesā€™ will you find?

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

How to Start?

Slide 89

Slide 89 text

@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

Slide 90

Slide 90 text

@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

Slide 91

Slide 91 text

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

Slide 92

Slide 92 text

@cafonsomota Compose: Project Structure androidApp/ desktopApp/ webApp/ shared/ Unsplash

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

@cafonsomota androidApp/ desktopApp/ webApp/ shared/ shared-ui/ :shared-ui androidMain/ commonMain/ desktopMain/ Compose: Project Structure

Slide 95

Slide 95 text

@cafonsomota Compose Compose for Android androidx.compose

Slide 96

Slide 96 text

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

Slide 97

Slide 97 text

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

Slide 98

Slide 98 text

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

Slide 99

Slide 99 text

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

Slide 100

Slide 100 text

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

Slide 101

Slide 101 text

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

Slide 102

Slide 102 text

Do I need to refactor The entire Project?

Slide 103

Slide 103 text

Do I need to refactor The entire Project? NO

Slide 104

Slide 104 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

Slide 105

Slide 105 text

What ā€˜challengesā€™ will you find?

Slide 106

Slide 106 text

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

Slide 107

Slide 107 text

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

Slide 108

Slide 108 text

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

Slide 109

Slide 109 text

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

Slide 110

Slide 110 text

How to Solve them

Slide 111

Slide 111 text

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

Slide 112

Slide 112 text

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

Slide 113

Slide 113 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 114

Slide 114 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 115

Slide 115 text

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

Slide 116

Slide 116 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 117

Slide 117 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 118

Slide 118 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 119

Slide 119 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 120

Slide 120 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 121

Slide 121 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 122

Slide 122 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 123

Slide 123 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 124

Slide 124 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 125

Slide 125 text

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

Slide 126

Slide 126 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 127

Slide 127 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 128

Slide 128 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 129

Slide 129 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 130

Slide 130 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 131

Slide 131 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 āš  Last supported version is 1.0.0-alpha3 (Kamel version 0.2.2)

Slide 132

Slide 132 text

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

Slide 133

Slide 133 text

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

Slide 134

Slide 134 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 135

Slide 135 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 136

Slide 136 text

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

Slide 137

Slide 137 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 138

Slide 138 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 139

Slide 139 text

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

Slide 140

Slide 140 text

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

Slide 141

Slide 141 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 142

Slide 142 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 143

Slide 143 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 144

Slide 144 text

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

Slide 145

Slide 145 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 146

Slide 146 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 147

Slide 147 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 148

Slide 148 text

Compose: WebApp What about Web? @cafonsomota

Slide 149

Slide 149 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 150

Slide 150 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 151

Slide 151 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 152

Slide 152 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 153

Slide 153 text

Getting everything together

Slide 154

Slide 154 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 155

Slide 155 text

Resources

Slide 156

Slide 156 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

Slide 157

Slide 157 text

Thereā€™s one more thing?

Slide 158

Slide 158 text

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

Slide 159

Slide 159 text

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

Slide 160

Slide 160 text

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

Slide 161

Slide 161 text

Photo by Hans Isaacson on Unsplash @cafonsomota An Android, A Desktop, and A Web Developer enter in a Bar