You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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
* 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
+
13
30
14
31
## Architecture
15
32
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.
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`.
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.
0 commit comments