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

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. “Kotlin's philosophy is that you don't have to migrate the

    entire application. Start from a easy place”
 
 -Jetbrains IS A SDK!
  2. 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
  3. KOTLIN MULTIPLATFORM Kotlin 
 Compiler Kotlin
 Multiplatform Native JS JVM

    JAR/AAR (For Android) JS (For React or Node) Binaries (For iOS)
  4. 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 {
  5. 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
  6. 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
  7. EXAMPLE •The most primitive way to save a primitive variable

    in Android and iOS is: SharedPreferences and NSUserDefaults
  8. 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.
  9. 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" ) }
  10. SAY HI TO KTOR! Ktor Kotlin Serialization Coroutines Retrofit Kotlin

    Serialization Coroutines /RxJava Alamofire RxSwift/ Composite Decode/ Encode/ etc…
  11. HTTP CLIENT // commonMain expect val engine: HttpClientEngine // androidMain

    actual val engine by lazy { Android.create() } // iosMain actual val engine by lazy { Ios.create() }
  12. HTTP CLIENT class GetDogsRepository { private val client = HttpClient(engine)

    { install(JsonFeature) { serializer = KotlinxSerializer().apply { register(Dogs.serializer().list) } } } suspend fun getDogs(): List<Dogs> = client.get("https://www.dogs.com.mx/isleofdogs") }
  13. COROUTINES SUPPORT! expect open class MyViewModel() { val clientScope: CoroutineScope

    protected open fun onCleared() } actual open class MyViewModel actual constructor(): ViewModel()
  14. 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() } } } }
  15. SAY HI TO SQLITEDELIGHT! •Databases are hard! •SQLDelight generates typesafe

    APIs from your SQL statements •Android and iOS use SQL
  16. 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');
  17. 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<Dogs> = db.selectAll().executeAsList() }
  18. 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
  19. APOLLO FOR MULTIPLATFORM •Apollo Runtime [Android] •Apollo API [iOS] •You

    can now add your schema.json and other graphql files under src/commonMain/graphql
  20. Magic and tricks: with Kotlin Multiplatform Unidos compartiendo y aprendiendo

    #SGVirtual Dinorah Tovar Lead Mobile Engineer @ddinorahtovar @ddinorahtovar @dinorahto @dinorahto