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

Droidkaigi 2019 flutter kotlin native

JB Lorenzo
February 08, 2019

Droidkaigi 2019 flutter kotlin native

JB Lorenzo

February 08, 2019
Tweet

More Decks by JB Lorenzo

Other Decks in Programming

Transcript

  1. @bennegeek Mobi Rem Cruz Mobi Cristiano
 Madeira Mobi JB Lorenzo

    UX Prod Hero Karen Banzon Mana ger Ayelen Chavez Mana ger Caio Moritz
  2. @bennegeek Mobi Rem Cruz Mobi Cristiano
 Madeira Mobi JB Lorenzo

    UX Prod Hero Karen Banzon Mana ger Ayelen Chavez Mana ger Caio Moritz * 3 devs * 2 managers * 1 ux/prod * /w real work * ~1 month deadline
  3. @bennegeek Outline: - Why? - How? (to Setup* (updated)) -

    How? (to link Flutter and Kotlin) - What? (pitfalls, considerations)
  4. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  5. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  6. @bennegeek // settings.gradle include ':app a ' def flutterProjectRoot =

    rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } include ':common' plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } project(":common").projectDir = new File(“../common”) enableFeaturePreview('GRADLE_METADATA')
  7. @bennegeek // settings.gradle include ':app a ' def flutterProjectRoot =

    rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } include ':common' plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } project(":common").projectDir = new File(“../common”) enableFeaturePreview('GRADLE_METADATA')
  8. @bennegeek // settings.gradle include ':app a ' def flutterProjectRoot =

    rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } include ':common' plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } project(":common").projectDir = new File(“../common”) enableFeaturePreview('GRADLE_METADATA')
  9. @bennegeek // settings.gradle include ':app a ' def flutterProjectRoot =

    rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } include ':common' plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } project(":common").projectDir = new File(“../common”) enableFeaturePreview('GRADLE_METADATA')
  10. @bennegeek // settings.gradle include ':app a ' def flutterProjectRoot =

    rootProject.projectDir.parentFile.toPath() def plugins = new Properties() def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') if (pluginsFile.exists()) { pluginsFile.withReader('UTF-8') { reader -> plugins.load(reader) } } include ':common' plugins.each { name, path -> def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() include ":$name" project(":$name").projectDir = pluginDirectory } project(":common").projectDir = new File(“../common”) enableFeaturePreview('GRADLE_METADATA')
  11. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  12. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  13. @bennegeek // build.gradle buildscript { ext.kotlin_version = '1.3.0' repositories {

    google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } // ...
  14. @bennegeek // build.gradle buildscript { ext.kotlin_version = '1.3.0' repositories {

    google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } // ...
  15. @bennegeek // build.gradle buildscript { ext.kotlin_version = '1.3.0' repositories {

    google() jcenter() } dependencies { classpath 'com.android.tools.build:gradle:3.3.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } // ...
  16. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  17. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  18. @bennegeek android \-- app \-- build.gradle \-- build.gradle \-- settings.gradle

    common a \-- build.gradle ios \-- Runner.xcodeproj lib
  19. @bennegeek android 1 \-- app \-- build.gradle \-- build.gradle \--

    settings.gradle common \-- build.gradle ios \-- Runner.xcodeproj lib
  20. @bennegeek // common / build.gradle apply plugin: 'kotlin-multiplatform' kotlin {

    targets { final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \ ? presets.iosArm64 : presets.iosX64 fromPreset(iOSTarget, 'iOS') { compilations.main.outputKinds('FRAMEWORK') } fromPreset(presets.jvm, 'android') } sourceSets { commonMain.dependencies { api 'org.jetbrains.kotlin:kotlin-stdlib-common' } androidMain.dependencies { api ‘org.jetbrains.kotlin:kotlin-stdlib' ¹ } } } // … task packForXCode(type: Sync) { finala File frameworkDir =aa new File(buildDir, "xcode-frameworks")a finala String mode =a project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG' inputs.property "mode", mode dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode) from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile } into frameworkDir doLast { new File(frameworkDir, 'gradlew').with { text =a "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '${rootProject.rootDir}'\n./gradlew \$@\n" setExecutable(true) } } } tasks.build.dependsOn packForXCode ¹ Dissecting Stdlib https://www.youtube.com/watch?v=Fzt_9I733Yg
  21. @bennegeek // common / a build.gradle apply plugin: 'kotlin-multiplatform' kotlin

    { targets { final def iOSTarget = System.getenv('SDK_NAME')?.startsWith("iphoneos") \ ? presets.iosArm64 : presets.iosX64 fromPreset(iOSTarget, 'iOS') { compilations.main.outputKinds('FRAMEWORK') } fromPreset(presets.jvm, 'android') } sourceSets { commonMain.dependencies { api 'org.jetbrains.kotlin:kotlin-stdlib-common' } androidMain.dependencies { api 'org.jetbrains.kotlin:kotlin-stdlib' } } } // ... task packForXCode(type: Sync) { final a File frameworkDir = aa new File(buildDir, "xcode-frameworks") a final a String mode = a project.findProperty("XCODE_CONFIGURATION")?.toUpperCase() ?: 'DEBUG' inputs.property "mode", mode dependsOn kotlin.targets.iOS.compilations.main.linkTaskName("FRAMEWORK", mode) from { kotlin.targets.iOS.compilations.main.getBinary("FRAMEWORK", mode).parentFile } into frameworkDir doLast { new File(frameworkDir, 'gradlew').with { text = a "#!/bin/bash\nexport 'JAVA_HOME=${System.getProperty("java.home")}'\ncd '$ {rootProject.rootDir}'\n./gradlew \$@\n" setExecutable(true) } } } tasks.build.dependsOn packForXCode
  22. @bennegeek android 1 \-- app \-- build.gradle 1 \-- build.gradle

    1 \-- settings.gradle common \-- build.gradle ios \-- Runner.xcodeproj lib
  23. @bennegeek android 1 \-- app \-- build.gradle 1 \-- build.gradle

    1 \-- settings.gradle common \-- build.gradle ios \-- Runner.xcodeproj lib
  24. @bennegeek iOS // AppDelegate.swift import YourFrameworkName // from Kotlin-Native //

    ... let channel = FlutterMethodChannel.init(name: "/channel", binaryMessenger: controller) channel.setMethodCallHandler({(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in // Process call.method and result }); GeneratedPluginRegistrant.register(with: self)
  25. @bennegeek * Serializing and Deserializing * Companion in Swift *

    arm32 * No Bitcode * Hot reload * JVM libraries Pitfalls
  26. @bennegeek Takeaways * Flutter is awesome for fast prototypes *

    You can replace Flutter with other cross platform UI frameworks while keeping your logic code in Kotlin/Native * Kotlin/Native are still in beta but is usable already though with some limitations * Kotlin/Native works well to reduce the amount of platform specific code * Some glue code needs to be written to pass around/ serialize objects * Don’t be afraid to try out new technologies (but …)