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

Kotlin Multiplatform - Analytics platform as example

Kotlin Multiplatform - Analytics platform as example

Alexander Gherschon

May 21, 2019
Tweet

More Decks by Alexander Gherschon

Other Decks in Programming

Transcript

  1. WHAT PLATFORMS • Android • Server (JVM, JS, …) •

    iOS • Javascript : React (Web), Electron (Desktop), Server (Node.js), … • Windows • Linux • WebAssembly • etc.
  2. Android WHAT CODE Networking UI Domain Business Logic iOS Networking

    UI Domain Business Logic REACTJS Networking UI Domain Business Logic
  3. Android WHAT CODE Networking UI Domain Business Logic iOS Networking

    UI Domain Business Logic REACTJS Networking UI Domain Business Logic
  4. Android WHAT CODE Networking UI Domain Business Logic iOS Networking

    UI Domain Business Logic REACTJS Networking UI Domain Business Logic
  5. WHAT PACKAGE Core Common Platform Specific Android Library (.aar) iOS

    (.Framework) Backend Library (.jar) Node.js Module
  6. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  7. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  8. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  9. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  10. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  11. targets { android() fromPreset(presets.iosArm64, 'iOS') { binaries { framework('Analytics') }

    } jvm('backend') js('node') { tasks.getByName(compilations.main.compileKotlinTaskName).kotlinOptions { metaInfo = true sourceMap = true moduleKind = 'commonjs' sourceMapEmbedSources = "always" } } } TARGETS
  12. sourceSets { commonMain { dependencies {} } backendMain { dependencies

    {} } nodeMain { dependencies {} } iOSMain { dependencies {} } } } SOURCESETS
  13. sourceSets { commonMain { dependencies {} } backendMain { dependencies

    {} } nodeMain { dependencies {} } iOSMain { dependencies {} } } } SOURCESETS
  14. sourceSets { commonMain { dependencies { implementation kotlin('stdlib-common') } }

    nodeMain { dependencies { implementation kotlin('stdlib-js') } } } } SOURCESETS
  15. sourceSets { commonMain { dependencies { implementation kotlin('stdlib-common') } }

    nodeMain { dependencies { implementation kotlin('stdlib-js') } } } } SOURCESETS
  16. sourceSets { commonMain { dependencies { implementation kotlin('stdlib-common') } }

    nodeMain { dependencies { implementation kotlin('stdlib-js') } } } } SOURCESETS
  17. MODELS enum class ScreenAction { ENTER, EXIT } enum class

    Platform { ANDROID, IOS, REACT } enum class Screen { HOME, DASHBOARD } data class Event( val name: String, val screen: Screen, val timestamp: Long, val platform: Platform )
  18. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  19. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  20. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  21. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  22. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  23. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  24. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  25. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  26. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  27. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  28. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  29. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  30. GOT THE TIME? // Common Sourceset expect fun getCurrentTimeMillis(): Long

    // Android/JVM Sourceset actual fun getCurrentTimeMillis(): Long { return System.currentTimeMillis() } // iOS Sourceset actual fun getCurrentTimeMillis(): Long { return NSDate().timeIntervalSince1970().toLong() } // Javascript Sourceset actual fun getCurrentTimeMillis(): Long { return Date().getTime().toLong() }
  31. GOT THE PLATFORM? // Common Sourceset expect fun getPlatform(): Platform

    // Android/JVM Sourceset actual fun getPlatform(): Platform = Platform.ANDROID // iOS Sourceset actual fun getPlatform(): Platform = Platform.IOS // Javascript Sourceset actual fun getPlatform(): Platform = Platform.REACT
  32. GOT THE PLATFORM? // Common Sourceset expect fun getPlatform(): Platform

    // Android/JVM Sourceset actual fun getPlatform(): Platform = Platform.ANDROID // iOS Sourceset actual fun getPlatform(): Platform = Platform.IOS // Javascript Sourceset actual fun getPlatform(): Platform = Platform.REACT
  33. GOT THE PLATFORM? // Common Sourceset expect fun getPlatform(): Platform

    // Android/JVM Sourceset actual fun getPlatform(): Platform = Platform.ANDROID // iOS Sourceset actual fun getPlatform(): Platform = Platform.IOS // Javascript Sourceset actual fun getPlatform(): Platform = Platform.REACT
  34. GOT THE PLATFORM? // Common Sourceset expect fun getPlatform(): Platform

    // Android/JVM Sourceset actual fun getPlatform(): Platform = Platform.ANDROID // iOS Sourceset actual fun getPlatform(): Platform = Platform.IOS // Javascript Sourceset actual fun getPlatform(): Platform = Platform.REACT
  35. GOT THE PLATFORM? // Common Sourceset expect fun getPlatform(): Platform

    // Android/JVM Sourceset actual fun getPlatform(): Platform = Platform.ANDROID // iOS Sourceset actual fun getPlatform(): Platform = Platform.IOS // Javascript Sourceset actual fun getPlatform(): Platform = Platform.REACT
  36. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  37. HELPER object EventsHelper { private fun logEvent(event: Event) { println("logging

    the event = $event") } fun enterScreen(screen: Screen) { logEvent(Event(name = ScreenAction.ENTER.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform()) ) } fun exitScreen(screen: Screen) { logEvent(Event(name = ScreenAction.EXIT.name, screen = screen, timestamp = getCurrentTimeMillis(), platform = getPlatform())) } }
  38. USING HELPER / ANDROID class HomeFragment : Fragment() { override

    fun onResume() { super.onResume() EventsHelper.enterScreen(Screen.HOME) } override fun onPause() { super.onPause() EventsHelper.exitScreen(Screen.HOME) } }
  39. USING HELPER / ANDROID class HomeFragment : Fragment() { override

    fun onResume() { super.onResume() EventsHelper.enterScreen(Screen.HOME) } override fun onPause() { super.onPause() EventsHelper.exitScreen(Screen.HOME) } }
  40. USING HELPER / REACT class HomeScreen : RComponent<RProps, RState>() {

    override fun componentDidMount() { EventsHelper.enterScreen(Screen.HOME) } override fun componentWillUnmount() { EventsHelper.exitScreen(Screen.HOME) } override fun RBuilder.render() {…} }
  41. USING HELPER / REACT class HomeScreen : RComponent<RProps, RState>() {

    override fun componentDidMount() { EventsHelper.enterScreen(Screen.HOME) } override fun componentWillUnmount() { EventsHelper.exitScreen(Screen.HOME) } override fun RBuilder.render() {…} }
  42. USING HELPER / IOS import UIKit import Analytics class HomeController:

    UIViewController { override func viewDidAppear(_ animated: Bool) { EventsHelper().enterScreen(screen: Screen.home) } override func viewDidDisappear(_ animated: Bool) { EventsHelper().exitScreen(screen: Screen.home) } }
  43. USING HELPER / IOS import UIKit import Analytics class HomeController:

    UIViewController { override func viewDidAppear(_ animated: Bool) { EventsHelper().enterScreen(screen: Screen.home) } override func viewDidDisappear(_ animated: Bool) { EventsHelper().exitScreen(screen: Screen.home) } }