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

Effective Multiplatform Architecture

Effective Multiplatform Architecture

Building multiplatform apps requires thinking about architecture a little differently than their single platform counterparts. Individually, each platform has their own norms and customs, filled with M's and V's and Promises, but they aren't alway a good fit to be shared with others. Often they have coupled relationships with the platforms for which they were designed that don't play nicely with others.

Over the past several months I've been migrating the Chicago Roboto app from a Kotlin first Android app to a multiplatform app, and have learned a lot about things that work well for one platform but not another, and how to make those feel a bit more native.

As I share the things I've learned with you, we'll discuss:

• Where to start the multiplatform conversion.
• Adapting native libraries
• Communicating between shared Kotlin code and native platforms
• Designing systems that non-Kotlin developers can get behind.

Ryan Harter

August 27, 2019
Tweet

More Decks by Ryan Harter

Other Decks in Programming

Transcript

  1. #DCNYC19 @rharter
    Effective Multiplatform
    Architecture
    #DCNYC19 @rharter
    Ryan Harter

    View Slide

  2. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  3. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  4. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  5. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    App
    App

    View Slide

  6. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    App
    App

    View Slide

  7. #DCNYC19 @rharter
    Multiplatform
    App App
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  8. #DCNYC19 @rharter

    View Slide

  9. #DCNYC19 @rharter
    Getting to Multiplatform
    #DCNYC19 @rharter
    Ryan Harter

    View Slide

  10. #DCNYC19 @rharter
    Step 0 - Modularize

    View Slide

  11. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time


    View Slide

  12. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)


    View Slide

  13. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)

    • Inversion of Control (Dependency Injection)


    View Slide

  14. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)

    • Inversion of Control (Dependency Injection)

    • Minimal platform dependencies


    View Slide

  15. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)

    • Inversion of Control (Dependency Injection)

    • Minimal platform dependencies

    • Limit to View and Repo dependencies


    View Slide

  16. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)

    • Inversion of Control (Dependency Injection)

    • Minimal platform dependencies

    • Limit to View and Repo dependencies

    • LiveData

    View Slide

  17. #DCNYC19 @rharter
    Modularize
    • Easier to migrate one module at a time

    • “clean” architecture is important (MVI)

    • Inversion of Control (Dependency Injection)

    • Minimal platform dependencies

    • Limit to View and Repo dependencies

    • LiveData

    View Slide

  18. #DCNYC19 @rharter
    Modularize
    Auth API
    Database
    Login Feature
    User Repo
    App

    View Slide

  19. #DCNYC19 @rharter
    Login Feature
    Auth API
    User Repo
    Modularize
    Database
    App

    View Slide

  20. #DCNYC19 @rharter
    Modularize
    Auth API
    Database
    Login Feature
    User Repo
    App

    View Slide

  21. #DCNYC19 @rharter
    Modularize
    Auth API
    Database
    Login Feature
    User Repo
    App

    View Slide

  22. #DCNYC19 @rharter
    Modularize
    Auth API
    Database
    Login Feature
    User Repo
    App

    View Slide

  23. #DCNYC19 @rharter
    Modularize
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  24. #DCNYC19 @rharter
    Multiplatform

    View Slide

  25. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  26. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  27. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App

    View Slide

  28. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Multiple Similar Apps
    Single App
    Multiple Different Apps App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API

    View Slide

  29. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  30. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    • All functionality needs to be replicated

    • Can start anywhere

    • Same approach as new app

    View Slide

  31. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  32. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  33. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App

    View Slide

  34. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App

    View Slide

  35. #DCNYC19 @rharter
    Single App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App

    View Slide

  36. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Multiple Similar Apps
    Single App
    Multiple Different Apps
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  37. #DCNYC19 @rharter
    Multiple Different Apps
    • Similar to modularization strategy

    • Convert to MPP as you modularize

    • Pick a feature to convert

    • Start from the bottom
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  38. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  39. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  40. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  41. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  42. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  43. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  44. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  45. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  46. #DCNYC19 @rharter
    Multiple Different Apps
    App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API

    View Slide

  47. #DCNYC19 @rharter
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    Multiple Different Apps

    View Slide

  48. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Multiple Similar Apps
    Single App
    Multiple Different Apps App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API

    View Slide

  49. #DCNYC19 @rharter
    Multiple Similar Apps
    • Multiple Approaches

    • New Feature

    • Vertical Migration

    • Horizontal Migration

    • Choice depends on existing arch, teams, etc.

    • Can be done with many small PRs (i.e. reduce risk)
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API

    View Slide

  50. #DCNYC19 @rharter
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    App
    Similar Apps - New Features

    View Slide

  51. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - New Features
    Subscription Feature

    View Slide

  52. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - New Features
    Subscription Feature

    View Slide

  53. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - New Features
    Subscription Feature

    View Slide

  54. #DCNYC19 @rharter
    Subscription Feature
    Common
    expect interface UserRepository {
    suspend fun getUser(): User
    suspend fun updateUser(user: User): User
    ...
    }

    View Slide

  55. #DCNYC19 @rharter
    Subscription Feature
    Common
    expect interface UserRepository {
    suspend fun getUser(): User
    suspend fun updateUser(user: User): User
    ...
    }

    View Slide

  56. #DCNYC19 @rharter
    Subscription Feature
    Common
    expect interface UserRepository {
    suspend fun getUser(): User
    suspend fun updateUser(user: User): User
    ...
    }
    iOS
    actual typealias UserRepository
    = backend.UserRepository
    JVM
    actual typealias UserRepository
    = com.example.myApp.backend.UserRepository

    View Slide

  57. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - New Features
    Subscription Feature

    View Slide

  58. #DCNYC19 @rharter
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    App
    Similar Apps - Vertical

    View Slide

  59. #DCNYC19 @rharter
    Similar Apps - Vertical
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Auth API

    View Slide

  60. #DCNYC19 @rharter
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - Vertical

    View Slide

  61. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Similar Apps - Vertical

    View Slide

  62. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Similar Apps - Vertical

    View Slide

  63. #DCNYC19 @rharter
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Similar Apps - Vertical

    View Slide

  64. #DCNYC19 @rharter
    User Repo
    Login Feature
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Login Feature
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    User Repo
    Similar Apps - Vertical

    View Slide

  65. #DCNYC19 @rharter
    Login Feature
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    Login Feature
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    User Repo
    Similar Apps - Vertical

    View Slide

  66. #DCNYC19 @rharter
    Login Feature
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    User Repo
    Login Feature
    Similar Apps - Vertical

    View Slide

  67. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Vertical

    View Slide

  68. #DCNYC19 @rharter
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    Auth API
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    App
    Similar Apps - Horizontal

    View Slide

  69. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal

    View Slide

  70. #DCNYC19 @rharter
    Database
    Login Feature
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal

    View Slide

  71. #DCNYC19 @rharter
    Database
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal

    View Slide

  72. #DCNYC19 @rharter
    Database
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal
    Account Feature
    Account Feature Library Feature

    View Slide

  73. #DCNYC19 @rharter
    Database
    User Repo Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal
    User Repo Social Repo Content Repo

    View Slide

  74. #DCNYC19 @rharter
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    App
    Similar Apps - Horizontal
    Database
    Activity API
    Content API
    Auth API
    Database
    Activity API
    Content API
    Auth API
    Auth API
    Database
    Activity API
    Content API

    View Slide

  75. #DCNYC19 @rharter
    Database
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal

    View Slide

  76. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    • Interface with platform implementations

    • Views

    • Repositories (or Use Cases)

    • Connected at both front and back

    • How to observe values?

    View Slide

  77. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories

    View Slide

  78. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View

    View Slide

  79. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View

    View Slide

  80. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ? ?
    ? ? ?

    View Slide

  81. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ? ?
    ✆ ✆ ✆

    View Slide

  82. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ? ?
    ☵ !☵ !☵

    View Slide

  83. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ?
    ☵ !☵ !☵
    ViewActions

    View Slide

  84. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState

    View Slide

  85. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState

    View Slide

  86. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState

    View Slide

  87. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState
    !⚛

    View Slide

  88. #DCNYC19 @rharter

    Common
    package org.reactivestreams.mpp
    expect interface Subscriber {
    fun onSubscribe(s: Subscription)
    fun onNext(t: T)
    fun onError(t: Throwable)
    fun onComplete()
    }

    View Slide

  89. #DCNYC19 @rharter

    Common
    JVM
    package org.reactivestreams.mpp
    actual typealias Subscriber
    = org.reactivestreams.Subscriber
    package org.reactivestreams.mpp
    expect interface Subscriber {
    fun onSubscribe(s: Subscription)
    fun onNext(t: T)
    fun onError(t: Throwable)
    fun onComplete()
    }

    View Slide

  90. #DCNYC19 @rharter

    package org.reactivestreams.mpp
    actual interface Subscriber {
    actual fun onSubscribe(s: Subscription)
    actual fun onNext(t: T)
    actual fun onError(t: Throwable)
    actual fun onComplete()
    }
    Common
    JVM
    iOS
    package org.reactivestreams.mpp
    actual typealias Subscriber
    = org.reactivestreams.Subscriber
    package org.reactivestreams.mpp
    expect interface Subscriber {
    fun onSubscribe(s: Subscription)
    fun onNext(t: T)
    fun onError(t: Throwable)
    fun onComplete()
    }

    View Slide

  91. #DCNYC19 @rharter

    package org.reactivestreams.mpp
    actual interface Subscriber {
    actual fun onSubscribe(s: Subscription)
    actual fun onNext(t: T)
    actual fun onError(t: Throwable)
    actual fun onComplete()
    }
    class BlockSubscriber(
    private val onNextBlock: (T) -> Unit,
    private val onErrorBlock: (Throwable) -> Unit,
    private val onCompleteBlock: () -> Unit
    ) : Subscriber, Disposable {
    ...
    }
    Common
    JVM
    iOS
    package org.reactivestreams.mpp
    actual typealias Subscriber
    = org.reactivestreams.Subscriber
    package org.reactivestreams.mpp
    expect interface Subscriber {
    fun onSubscribe(s: Subscription)
    fun onNext(t: T)
    fun onError(t: Throwable)
    fun onComplete()
    }

    View Slide

  92. #DCNYC19 @rharter

    package org.reactivestreams.mpp
    actual interface Subscriber {
    actual fun onSubscribe(s: Subscription)
    actual fun onNext(t: T)
    actual fun onError(t: Throwable)
    actual fun onComplete()
    }
    class BlockSubscriber(
    private val onNextBlock: (T) -> Unit,
    private val onErrorBlock: (Throwable) -> Unit,
    private val onCompleteBlock: () -> Unit
    ) : Subscriber, Disposable {
    ...
    }
    iOS
    extension Reactive_streams_mppPublisher {
    func subscribe(
    onNext onNextBlock: @escaping (T) -> Void,
    onError onErrorBlock: @escaping (Error) -> Void,
    onComplete onCompleteBlock: @escaping () -> Void
    ) -> Disposable {
    let subscriber = BlockSubscriber(
    onNextBlock: onNextBlock,
    onErrorBlock: onErrorBlock,
    onCompleteBlock: onCompleteBlock
    )
    subscribe(s: subscriber)
    return subscriber
    }
    }
    iOS - Swift

    View Slide

  93. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState
    !⚛

    View Slide

  94. #DCNYC19 @rharter
    Login Feature
    ViewModel

    View Slide

  95. #DCNYC19 @rharter
    Login Feature
    ViewModel
    Common
    package com.chicagoroboto.features.shared
    expect interface ViewModel {
    val viewState: Flow
    }

    View Slide

  96. #DCNYC19 @rharter
    Login Feature
    JVM
    ViewModel
    Common
    package com.chicagoroboto.features.shared
    expect interface ViewModel {
    val viewState: Flow
    }
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    }

    View Slide

  97. #DCNYC19 @rharter
    Login Feature
    Common
    JVM
    package com.chicagoroboto.features.shared
    expect interface ViewModel {
    val viewState: Flow
    }
    ViewModel
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    }
    iOS
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    fun viewState(): Publisher
    = viewState.asPublisher()
    }
    fun viewState(): Publisher
    = viewState.asPublisher()

    View Slide

  98. #DCNYC19 @rharter
    Login Feature
    ViewModel
    Common
    JVM
    package com.chicagoroboto.features.shared
    expect interface ViewModel {
    val viewState: Flow
    }
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    }
    iOS
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    fun viewState(): Publisher
    = viewState.asPublisher()
    }
    fun viewState(): Publisher
    = viewState.asPublisher()

    View Slide

  99. #DCNYC19 @rharter
    Login Feature
    SessionListViewModel
    class SessionListViewModel(
    private val sessionRepo: SessionRepository,
    speakerRepo SpeakerRepository,
    favoriteRepo: FavoriteRepository
    ) : ViewModel {
    private val dateChannel = ConflatedBroadcastChannel()
    private val sessionFlow: Flow> = dateChannel.asFlow()
    .flatMapConcat { sessionRepo.sessionsForDate(it) }
    private val speakerFlow: Flow> = speakerRepo.getSpeakers()
    private val favoriteFlow: Flow> = favoriteRepo.getFavorites()
    override val viewState = combine(sessionFlow, speakerFlow, favoriteFlow) {
    sessions, speakers, favorites ->
    SessionListViewState(date, viewSessions)
    }
    }

    View Slide

  100. #DCNYC19 @rharter
    Login Feature
    SessionListViewModel
    override val viewState = combine(sessionFlow, speakerFlow, favoriteFlow) {
    sessions, speakers, favorites ->
    SessionListViewState(date, viewSessions)
    }
    class SessionListViewModel(
    private val sessionRepo: SessionRepository,
    speakerRepo SpeakerRepository,
    favoriteRepo: FavoriteRepository
    ) : ViewModel {
    private val dateChannel = ConflatedBroadcastChannel()
    private val sessionFlow: Flow> = dateChannel.asFlow()
    .flatMapConcat { sessionRepo.sessionsForDate(it) }
    private val speakerFlow: Flow> = speakerRepo.getSpeakers()
    private val favoriteFlow: Flow> = favoriteRepo.getFavorites()
    override val viewState = combine(sessionFlow, speakerFlow, favoriteFlow) {
    sessions, speakers, favorites ->
    SessionListViewState(date, viewSessions)
    }
    }

    View Slide

  101. #DCNYC19 @rharter
    iOS App
    .subscribe(
    onNext: { [weak self] (state: SessionListViewState) in
    self?.sessions = state.sessions
    },
    onError: { error in
    NSLog("Failed to load state.", error)
    },
    onComplete: {
    NSLog("onComplete")
    }
    )
    class SessionListViewController: UICollectionViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    disposables <= self.viewModel.viewState()
    .subscribe(
    onNext: { [weak self] (state: SessionListViewState) in
    self?.sessions = state.sessions
    },
    onError: { error in
    NSLog("Failed to load state.", error)
    },
    onComplete: {
    NSLog("onComplete")
    }
    )
    self.viewModel.setDate(date: self.date)
    }
    }

    View Slide

  102. #DCNYC19 @rharter
    iOS App
    .subscribe(
    onNext: { [weak self] (state: SessionListViewState) in
    self?.sessions = state.sessions
    },
    onError: { error in
    NSLog("Failed to load state.", error)
    },
    onComplete: {
    NSLog("onComplete")
    }
    )
    class SessionListViewController: UICollectionViewController {
    override func viewDidLoad() {
    super.viewDidLoad()
    disposables <= self.viewModel.viewState()
    .subscribe(
    onNext: { [weak self] (state: SessionListViewState) in
    self?.sessions = state.sessions
    },
    onError: { error in
    NSLog("Failed to load state.", error)
    },
    onComplete: {
    NSLog("onComplete")
    }
    )
    self.viewModel.setDate(date: self.date)
    }
    }

    View Slide

  103. #DCNYC19 @rharter
    Login Feature
    Common
    JVM
    package com.chicagoroboto.features.shared
    expect interface ViewModel {
    val viewState: Flow
    }
    ViewModel
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    }
    iOS
    package com.chicagoroboto.features.shared
    actual interface ViewModel {
    actual val viewState: Flow
    fun viewState(): Publisher
    = viewState.asPublisher()
    }
    fun viewState(): Publisher
    = viewState.asPublisher()

    View Slide

  104. #DCNYC19 @rharter
    Login Feature
    Feature Layer
    To Repositories
    To View
    ☵ !☵ !☵
    ViewActions ViewState
    !⚛

    View Slide

  105. #DCNYC19 @rharter
    Database
    User Repo
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    App
    Similar Apps - Horizontal

    View Slide

  106. #DCNYC19 @rharter
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    App
    Similar Apps - Horizontal
    Auth API
    Database
    Activity API
    Content API

    View Slide

  107. #DCNYC19 @rharter
    Multiplatform
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Multiple Similar Apps
    Single App
    Multiple Different Apps App
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature Library Feature
    Social Repo Content Repo
    Activity API
    Content API
    Auth API
    Database
    Login Feature
    User Repo
    App
    Account Feature
    Library Feature
    Social Repo
    Content Repo
    Activity API
    Content API

    View Slide

  108. #DCNYC19 @rharter
    Effective Multiplatform
    Architecture
    #DCNYC19 @rharter
    Ryan Harter

    View Slide