Skip to content

Commit 9c142e0

Browse files
authored
Update README.md
1 parent b12cf1c commit 9c142e0

File tree

1 file changed

+45
-4
lines changed

1 file changed

+45
-4
lines changed

README.md

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,53 @@ __iOS Build & Tests____
99

1010
[![Bitrise](https://app.bitrise.io/app/3eaf4fa6c0750504/status.svg?token=N7jdGFn6dvfLcuKZaBMW1g)](https://app.bitrise.io/app/3eaf4fa6c0750504#/builds)
1111

12-
A Kotlin multiplatform (Android/iOS) WT name game.
12+
A Kotlin multiplatform (Android/iOS) WT name game. Player is shown a picture and must guess the name. User can select from Cats, Dogs, or Trees! (aka Willowtree employees). The app utilizes the following:
13+
* [Ktor](https://ktor.io/clients/http-client.html) for networking
14+
* [Kotlinx Serialization](https://github.com/Kotlin/kotlinx.serialization)
15+
* [Multiplatform Settings](https://github.com/russhwolf/multiplatform-settings)
16+
* fork of [Reduks](https://github.com/beyondeye/Reduks/tree/3.x_kotlin_1_3) (kotlin redux implementation)
17+
18+
19+
## Android
20+
Building and testing the Android App can be completed with:
21+
```./gradlew build```
22+
or install with:
23+
```./gradle androidInstall```
24+
or opened and ran in Android Studio
25+
26+
27+
## iOS
28+
The iOS workspace in `/iOS/NameGame` can be open and ran from xCode or AppCode. A run script has been added to the build phase that will compile the common code into a framework which can be used for the project.
29+
1330

1431
## Architecture
1532

16-
App uses an MVP arch with a redux store as the 'Model'. This approach allows maximum reuse of code and a simple contract for the platforms to satisfy.
33+
A `GameEngine` object holds the state of the app and provides a methods for views (fragments/UIViewControllers) to "attach". The `GameEngine` is initialized in the Application class on Android, and the AppDelegate on iOS. Each view must attach/detach from the GameEngine when it is visible. `GameEngine.attachView(view)` returns the appropriate presenter for the view.
34+
35+
`BaseNameGameViewFragment` & `BaseNameGameViewController` handle attaching/detaching the presenter at the appropriate lifecycle methods. Each Fragment/ViewController extends from these.
36+
37+
An MVP arch is used with a redux store as the 'Model'. This approach allows maximum reuse of code and a simple contract for the platforms to satisfy. Presenters send `ViewStates` (simple data classes with fields needed to render UI) to the View interface. The View implementation has a reference to the presenter, and calls methods for user interaction. This creates a unidirectional dataflow:
38+
39+
User interaction -> Dispatch Action -> new state (reduce) -> view rendered by presenter
40+
41+
## "Dumb Views"
42+
Views in this arch are truely 'dumb' - they should contain nearly no logic. They are responsible for rendering the view based on the `ViewState` given to them by the presenter.
43+
44+
## Presenters
45+
46+
![](https://storage.googleapis.com/treestorage/ui_f_of_state.png)
47+
48+
49+
Presenters give a layer of control between subscribing to the new state and the View. Having views subscribing directly to the store results in code and logic in the View which must be duplicated on each platform. Presenters are singleton objects that contain no state other than the previous AppState. This works while presenters are for an entire screen, which for this app is the case. Another approach will be needed if multiple instances of a given presenter are needed. The presenter is responsible for rendering the view given the AppState or the delta in AppState. The Reduks library has a port of Reselect, which allows calling code only when a property changes. Presenters pass `ViewState` to View methods. All transformations from Appstate -> ViewState are extension functions in `Transformations.kt`.
50+
51+
52+
53+
![arch diagram](https://storage.googleapis.com/treestorage/Kotlin%20MPP%20Demo%20Arch.png)
54+
55+
## Async Actions
56+
In redux world there are many ways to handle creation of async actions. `Thunks` have been used in this app. `NetworkThunks` and `TimerThunks` both use coroutines to launch concurrent operations that dispatch actions.
57+
58+
## Navigation
59+
In this app, Navigation is considered a side effect of the AppState. The `NavigationMiddleware` handles changing screens based on dispatched actions. The `NavigationMiddleware` takes an implementation of `Navigator` which is implemeneted for each platform.
1760

18-
![](https://storage.googleapis.com/treestorage/Kotlin%20MPP%20Demo%20Arch.png)
1961

20-
WIP...

0 commit comments

Comments
 (0)