$30 off During Our Annual Pro Sale. View Details »

Magic and Tricks with Kotlin Multiplatform

Magic and Tricks with Kotlin Multiplatform

This talk is for mobile engineers that have experience with Swift or Kotlin for iOS and Android We will cover the getting started guide for all the developers that are interested in moving to Kotlin Multiplatform as a production-ready tool, taking into consideration all the pitfalls and advantages we can have using it, we will cover some simple clever things you can do with Ktor and SQLiteDelight to simplify modularization, take advantages of Serialization, and the terrific world of Kotlin Multiplatform. Talking about how to shape your architecture for a production app, and sharing your architecture, without leaving behind the OS, the security and the performance of your app, sometimes we forgot that for a good production app we need a good architecture that is testable, that is taking consideration of concurrency and databases.

Dinorah Tovar

April 24, 2020
Tweet

More Decks by Dinorah Tovar

Other Decks in Technology

Transcript

  1. Magic and tricks: with
    Kotlin Multiplatform
    Dinorah Tovar
    Unidos compartiendo y aprendiendo
    #SGVirtual

    View Slide

  2. DISCLAIMER!

    View Slide

  3. KOTLIN

    IS COOL

    View Slide

  4. KOTLIN MULTIPLATFORM 

    IS COOLER

    View Slide

  5. KOTLIN IS A JVM LANGUAGE,
    NOT AN ANDROID LANGUAGE

    View Slide

  6. WHAT THE HECK IS KMP?

    View Slide

  7. TRY IT BEFORE YOU BUY IT
    FULL OPTIONAL

    View Slide

  8. SHARING CODE

    View Slide

  9. SO, IS CROSS-PLATFORM? OR A
    FRAMEWORK
    KINDA CROSS

    View Slide

  10. ONLY LOGIC, NO UI

    View Slide

  11. ONLY LOGIC, “NO UI”

    View Slide

  12. View Slide

  13. SO, WHAT THE HECK IS? IS A
    FRAMEWORK? A SDK? A PLUGIN?

    View Slide

  14. “Kotlin's philosophy is that you don't have to migrate the entire application.
    Start from a easy place”


    -Jetbrains
    IS A SDK!

    View Slide

  15. SHARED BUSINESS LOGIC

    View Slide

  16. SHARED BUSINESS LOGIC
    • Not restrictions
    •Appearance and behavior is the same
    •Performance is fully Native!

    View Slide

  17. ANDROID AND IOS ARE KINDA THE SAME, RIGHT?
    •They are “Unix like”
    •They have multithreading operations
    •They have file/primitive saving of data and pretty
    much, they use SQL

    View Slide

  18. HOW DOES IT WORK?

    View Slide

  19. KOTLIN MULTIPLATFORM
    Kotlin 

    Compiler
    Kotlin

    Multiplatform
    Native JS JVM
    JAR/AAR (For Android)
    JS (For React or Node)
    Binaries (For iOS)

    View Slide

  20. KOTLIN MULTIPLATFORM

    View Slide

  21. KOTLIN MULTIPLATFORM
    sourceSets {
    commonMain {
    dependencies {
    api project(":common-all")
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-common'
    ---
    }
    }
    commonTest {
    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-test-common"
    ---
    }
    }
    androidMain {
    dependsOn commonMain
    dependencies {

    View Slide

  22. commonTest {
    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-test-common"
    ---
    }
    }
    androidMain {
    dependsOn commonMain
    dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    ---
    }
    }
    iOSMain {
    dependsOn commonMain
    dependencies {
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core-native:
    $coroutines_version"
    ----
    }
    }
    }
    KOTLIN MULTIPLATFORM

    View Slide

  23. I DON’T GET IT, SHARING
    CODE? HOW?

    View Slide

  24. KOTLIN MULTIPLATFORM
    •Use a Plugin in your grade to configure your “blocks”
    •We configure a Kotlin block, with our targets! One for
    Android and one for iOS

    View Slide

  25. KOTLIN MULTIPLATFORM

    View Slide

  26. EXAMPLE
    •The most primitive way to save a primitive variable in
    Android and iOS is: SharedPreferences and
    NSUserDefaults

    View Slide

  27. EXAMPLE
    •The most primitive way to save a primitive variable in
    Android and iOS is: SharedPreferences and
    NSUserDefaults
    •Kotlin only knows how to compile Kotlin code into
    different targets but you can make Kotlin aware of
    this by using the expect/actual mechanism.

    View Slide

  28. SAVING VALUES
    //Common Code
    expect fun saveValueLocally(value: String)
    //Android Code
    actual fun saveValueLocally(value: String) {
    //Create shared preferences
    sharedPreferences.edit { putString("Value", value) }
    }
    //iOS Code
    actual fun saveValueLocally(value: String) {
    NSUserDefaults.standardUserDefaults.setValue(
    value,
    forKey = "Value"
    )
    }

    View Slide

  29. MULTITHREADING

    View Slide

  30. SAY HI TO KTOR!
    Ktor
    Kotlin
    Serialization
    Coroutines
    Retrofit
    Kotlin
    Serialization
    Coroutines
    /RxJava
    Alamofire
    RxSwift/
    Composite
    Decode/
    Encode/
    etc…

    View Slide

  31. HTTP CLIENT
    // commonMain
    expect val engine: HttpClientEngine
    // androidMain
    actual val engine by lazy { Android.create() }
    // iosMain
    actual val engine by lazy { Ios.create() }

    View Slide

  32. HTTP CLIENT
    class GetDogsRepository {
    private val client = HttpClient(engine) {
    install(JsonFeature) {
    serializer = KotlinxSerializer().apply {
    register(Dogs.serializer().list)
    }
    }
    }
    suspend fun getDogs(): List =
    client.get("https://www.dogs.com.mx/isleofdogs")
    }

    View Slide

  33. COROUTINES SUPPORT!
    expect open class MyViewModel() {
    val clientScope: CoroutineScope
    protected open fun onCleared()
    }
    actual open class MyViewModel actual constructor(): ViewModel()

    View Slide

  34. COROUTINES SUPPORT FOR IOS… KINDA
    Coroutines
    Hot
    Streams
    Cold
    Streams

    View Slide

  35. COROUTINES SUPPORT FOR IOS… KINDA
    actual open class MyViewModel actual constructor() {
    private val viewModelJob = SupervisorJob()
    val viewModelScope: CoroutineScope = CoroutineScope(IosMainDispatcher + viewModelJob)
    actual val clientScope: CoroutineScope = viewModelScope
    protected actual open fun onCleared() {
    viewModelJob.cancelChildren()
    }
    object IosMainDispatcher : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
    dispatch_async(dispatch_get_main_queue()) { block.run() }
    }
    }
    }

    View Slide

  36. OKIO AND OKHTTP

    View Slide

  37. OKIO AND OKHTTP

    View Slide

  38. DATABASES

    View Slide

  39. SAY HI TO SQLITEDELIGHT!
    •Databases are hard!
    •SQLDelight generates typesafe APIs from your SQL
    statements
    •Android and iOS use SQL

    View Slide

  40. SAY HI TO SQLITEDELIGHT!
    CREATE TABLE dogs (
    dogName TEXT NOT NULL,
    dogRace TEXT NOT NULL
    );

    insert:
    INSERT INTO dogs (dogName, dogRace)
    VALUES ('Spots', 'Best friend');

    View Slide

  41. FULL SUPPORT FOR IOS AND ANDROID
    class DogsDao(database: Dogs) {
    private val db = database.dogsModelQueries
    internal fun insert(item: Dogs) {
    db.insertItem(
    dogName = item.dogName,
    dogRace = item.dogRace
    )
    }
    internal fun select():List = db.selectAll().executeAsList()
    }

    View Slide

  42. FIREBASE

    View Slide

  43. FIREBASE PLUGIN

    View Slide

  44. GRAPHQL

    View Slide

  45. APOLLO FOR MULTIPLATFORM
    •Apollo queries can be really complicated
    •One wrong detail in the query and there will be
    nothing in the tree to search

    View Slide

  46. APOLLO FOR MULTIPLATFORM

    View Slide

  47. APOLLO FOR MULTIPLATFORM
    •Apollo Runtime [Android]
    •Apollo API [iOS]
    •You can now add your schema.json and other
    graphql files under src/commonMain/graphql

    View Slide

  48. THE REAL QUESTION?, IS
    READY FOR PROD?

    View Slide

  49. WAIT FOR THE FUTURE

    View Slide

  50. Magic and tricks: with
    Kotlin Multiplatform
    Unidos compartiendo y aprendiendo
    #SGVirtual
    Dinorah Tovar
    Lead Mobile Engineer
    @ddinorahtovar
    @ddinorahtovar
    @dinorahto
    @dinorahto

    View Slide