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

Getting started with Kotlin/Native in a project near you

Stefan M.
October 29, 2019

Getting started with Kotlin/Native in a project near you

Given at an internal company event.

Want to getting started with Kotlin/Native in your Android and iOS TODAY?
Fine, let's do it.
In this talk I present how to setup everything so that we can start coding on a shared library for both platforms.

Stefan M.

October 29, 2019
Tweet

More Decks by Stefan M.

Other Decks in Programming

Transcript

  1. Getting started with
    Kotlin/Native
    in a project near you

    View full-size slide

  2. Kotlin/Native
    Kotlin/Multiplatform

    View full-size slide

  3. Kotlin + /JVM + /Native + /JS
    =
    Kotlin/Multiplatform

    View full-size slide

  4. Kotlin + /JVM + /Native + /JS
    =
    Kotlin/Multiplatform

    View full-size slide

  5. We have a problem
    in the Kotlin/Multiplatform docs

    View full-size slide

  6. .
    ├── SharedCode
    │ └── src
    │ ├── commonMain
    │ ├── androidMain
    │ └── iosMain
    ├── android
    │ └── src
    │ ├── main
    │ ├── test
    │ └── androidTest
    ├── native
    │ └── KotlinIOS
    │ ├── KotlinIOS
    │ ├── KotlinIOSTests
    │ └── KotlinIOSUITests
    └── ...
    Taken from
    github.com/kotlin-hands-on/mpp-ios-android

    View full-size slide

  7. someProjectRepo
    /iOS
    someProjectRepo
    /Android

    View full-size slide

  8. someProjectRepo
    /iOS
    someProjectRepo
    /Android
    someProjectRepo
    /mobile

    View full-size slide

  9. someProjectRepo
    /iOS
    someProjectRepo
    /Android
    someProjectRepo
    /mobile

    View full-size slide

  10. an independent project creates artifacts
    (Jar & Framework)

    View full-size slide

  11. which can be published

    View full-size slide

  12. and imported in our existing projects
    // Gradle (Android)
    repositories {
    maven(url = "https://artifactory.some.thing")
    }
    dependencies {
    implementation("something:sharedLib:1.0.0")
    }
    // Carthage (iOS)
    binary "https://artifactory.some.thing/something/sharedLib.json" ~> 1.0.0

    View full-size slide

  13. iOS devs...
    welcome to the world of Gradle

    View full-size slide

  14. plugins {
    kotlin("multiplatform") version "1.3.50"
    }
    kotlin {
    jvm()
    // This is for real iDevices
    iosArm64().binaries.framework()
    // This is for simulators
    iosX64().binaries.framework()
    }
    repositories {
    jcenter()
    }
    val jvmMainImplementation by configurations
    dependencies {
    commonMainImplementation(kotlin("stdlib-common"))
    jvmMainImplementation(kotlin("stdlib-jdk8"))
    }

    View full-size slide

  15. That's it
    Happy coding y'all

    View full-size slide

  16. Uhm.. sorry.
    But you said something about
    artifacts and publishing

    View full-size slide

  17. Build tasks
    -----------
    - jvmJar
    - linkDebugFrameworkIosArm64
    - linkDebugFrameworkIosX64
    - linkReleaseFrameworkIosArm64
    - linkReleaseFrameworkIosX64
    Artifacts - Jar and Framework
    ./gradlew tasks

    View full-size slide

  18. pluginManager.apply("maven-publish")
    // Setup our artifactory repository
    extensions.getByType(PublishingExtension::class.java).apply {
    repositories { repoHandler ->
    repoHandler.maven {
    it.name = "Artifactory"
    it.url = project.uri("https://artifactory.some.thing/something")
    it.credentials { credentials ->
    credentials.username = properties["artifactoryUser"] as? String
    credentials.password = properties["artifactoryKey"] as? String
    }
    }
    }
    }
    Publishing - Jar

    View full-size slide

  19. // Creates a task to pack the `iosArm64` & `iosX64` Frameworks
    // into one Framework.
    // This is because the Simulator and Devices running on different platforms.
    // Therefore we need a Framework which runs on both.
    val fatFrameworkTask = tasks.register("releaseFatFramework", FatFrameworkTask::class) {

    }
    // Well, it's complicated!
    Publishing - Framework

    View full-size slide

  20. We are using Carthage as a…
    "dependency manager"*
    *Seems only Gradle users get this joke

    View full-size slide

  21. FatFramework
    kotlin {
    iosArm64().binaries.framework {
    baseName = "sharedLib"
    }
    iosX64().binaries.framework {
    baseName = "sharedLib"
    }
    }
    val fatFrameworkTask = tasks.register("releaseFatFramework", FatFrameworkTask::class) {
    baseName = "sharedLib"
    from(
    kotlin.iosArm64().binaries.getFramework("RELEASE"),
    kotlin.iosX64().binaries.getFramework("RELEASE")
    )
    }

    View full-size slide

  22. ...Zipp it and publish
    val zipFramework = tasks.register("zipFatFramework", Zip::class.java) {
    it.dependsOn(tasks.named("releaseFatFramework"))
    it.from("$buildDir/fat-framework")
    it.archiveFileName.set("sharedLib.framework.zip")
    it.destinationDirectory.set(file("$buildDir/fat-framework-zip"))
    }
    tasks.register("publishFatFrameworkToArtifactory", Exec::class.java) {
    it.dependsOn(tasks.named("releaseFatFramework"), zipFramework)
    it.commandLine("jfrog", "magic")
    }

    View full-size slide

  23. Create a JSON file for "versioning"
    /**
    * // The code should generate something like this:
    * ```
    * {
    * "1.0.0": "https://artifactory.some.thing/1.0.0/shared.Framework.zip",
    * "1.0.1": "https://artifactory.some.thing/1.0.1/shared.Framework.zip",
    * "1.1.0": "https://artifactory.some.thing/1.1.0/shared.Framework.zip"
    * }
    * ```
    * Basically a `version <-> Framework location` mapping.
    */

    View full-size slide

  24. ...and publish it as well
    tasks.register("publishFrameworkJsonToArtifactory", Exec::class.java) {
    it.dependsOn(downloadAndModifyJson)
    it.commandLine("jfrog", "magic")
    }

    View full-size slide