Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

#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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

#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

Slide 6

Slide 6 text

#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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

#DCNYC19 @rharter

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

#DCNYC19 @rharter Step 0 - Modularize

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

#DCNYC19 @rharter Modularize • Easier to migrate one module at a time • “clean” architecture is important (MVI) •

Slide 13

Slide 13 text

#DCNYC19 @rharter Modularize • Easier to migrate one module at a time • “clean” architecture is important (MVI) • Inversion of Control (Dependency Injection) •

Slide 14

Slide 14 text

#DCNYC19 @rharter Modularize • Easier to migrate one module at a time • “clean” architecture is important (MVI) • Inversion of Control (Dependency Injection) • Minimal platform dependencies •

Slide 15

Slide 15 text

#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 •

Slide 16

Slide 16 text

#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

Slide 17

Slide 17 text

#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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

#DCNYC19 @rharter Multiplatform

Slide 25

Slide 25 text

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

Slide 26

Slide 26 text

#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

Slide 27

Slide 27 text

#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

Slide 28

Slide 28 text

#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

Slide 29

Slide 29 text

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

Slide 30

Slide 30 text

#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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

#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

Slide 34

Slide 34 text

#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

Slide 35

Slide 35 text

#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

Slide 36

Slide 36 text

#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

Slide 37

Slide 37 text

#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

Slide 38

Slide 38 text

#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

Slide 39

Slide 39 text

#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

Slide 40

Slide 40 text

#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

Slide 41

Slide 41 text

#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

Slide 42

Slide 42 text

#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

Slide 43

Slide 43 text

#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

Slide 44

Slide 44 text

#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

Slide 45

Slide 45 text

#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

Slide 46

Slide 46 text

#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

Slide 47

Slide 47 text

#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

Slide 48

Slide 48 text

#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

Slide 49

Slide 49 text

#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

Slide 50

Slide 50 text

#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

Slide 51

Slide 51 text

#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

Slide 52

Slide 52 text

#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

Slide 53

Slide 53 text

#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

Slide 54

Slide 54 text

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

Slide 55

Slide 55 text

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

Slide 56

Slide 56 text

#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

Slide 57

Slide 57 text

#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

Slide 58

Slide 58 text

#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

Slide 59

Slide 59 text

#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

Slide 60

Slide 60 text

#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

Slide 61

Slide 61 text

#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

Slide 62

Slide 62 text

#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

Slide 63

Slide 63 text

#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

Slide 64

Slide 64 text

#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

Slide 65

Slide 65 text

#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

Slide 66

Slide 66 text

#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

Slide 67

Slide 67 text

#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

Slide 68

Slide 68 text

#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

Slide 69

Slide 69 text

#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

Slide 70

Slide 70 text

#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

Slide 71

Slide 71 text

#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

Slide 72

Slide 72 text

#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

Slide 73

Slide 73 text

#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

Slide 74

Slide 74 text

#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

Slide 75

Slide 75 text

#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

Slide 76

Slide 76 text

#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?

Slide 77

Slide 77 text

#DCNYC19 @rharter Login Feature Feature Layer To Repositories

Slide 78

Slide 78 text

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

Slide 79

Slide 79 text

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

Slide 80

Slide 80 text

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

Slide 81

Slide 81 text

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

Slide 82

Slide 82 text

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

Slide 83

Slide 83 text

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

Slide 84

Slide 84 text

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

Slide 85

Slide 85 text

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

Slide 86

Slide 86 text

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

Slide 87

Slide 87 text

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

Slide 88

Slide 88 text

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

Slide 89

Slide 89 text

#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() }

Slide 90

Slide 90 text

#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() }

Slide 91

Slide 91 text

#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() }

Slide 92

Slide 92 text

#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

Slide 93

Slide 93 text

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

Slide 94

Slide 94 text

#DCNYC19 @rharter Login Feature ViewModel

Slide 95

Slide 95 text

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

Slide 96

Slide 96 text

#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 }

Slide 97

Slide 97 text

#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()

Slide 98

Slide 98 text

#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()

Slide 99

Slide 99 text

#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) } }

Slide 100

Slide 100 text

#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) } }

Slide 101

Slide 101 text

#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) } }

Slide 102

Slide 102 text

#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) } }

Slide 103

Slide 103 text

#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()

Slide 104

Slide 104 text

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

Slide 105

Slide 105 text

#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

Slide 106

Slide 106 text

#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

Slide 107

Slide 107 text

#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

Slide 108

Slide 108 text

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