Extendable MVI framework for Kotlin Multiplatform with powerful debugging tools (logging and time travel), inspired by Badoo MVICore library

Overview

Maven Central License kotlinlang|MVIKotlin

Should you have any questions or ideas please welcome to the Slack channel: #mvikotlin

Inspiration

This project is inspired by Badoo MVICore library.

Overview

What is MVI

MVI stands for Model-View-Intent. It is an architectural pattern that utilizes unidirectional data flow. The data circulates between Model and View only in one direction - from Model to View and from View to Model.

MVI

What is MVIKotlin

MVIKotlin is a Kotlin Multiplatform framework that provides a way of (not only) writing shared code using MVI pattern. It also includes powerful debug tools like logging and time travel. The main functionality of the framework does not depend on any reactive nor coroutines library. Extensions for Reaktive and for Coroutines libraries are provided as separate modules.

MVIKotlin

Responsibility

MVIKotlin does not bring or enforce any particular architecture. Its responsibility can be described as follows:

  • To provide a single source of truth for State (the scope is not defined, it can be a whole app, a screen, a feature, or a part of a feature);
  • To provide an abstraction for UI with efficient updates (however this is not obligatory, you can use whatever you want);
  • To provide lifecycle aware connections (binding) between inputs and outputs (again this is not obligatory in any way).

Everything else is out of scope of the library, there are no definitions for "screens", "features", "modules", etc. Also, no particular reactive framework is enforced/exposed. This gives a lot of flexibility:

  • MVIKotlin can be introduced incrementally (e.g. you can start using it in a small feature and then expand gradually);
  • You can use/experiment with different architectures, approaches and/or libraries for navigation, UI, modularization, etc;
  • Use whatever reactive framework you like or don't use it at all.

You can find one of the architecture options in the samples. Again, this is just an example of one possible solution.

Setup

Recommended minimum Gradle version is 5.3. Please read first the documentation about metadata publishing mode.

There are a number of modules published to Maven Central:

  • mvikotlin - core interfaces and functionality (multiplatform)
  • mvikotlin-main - the main module with the default Store implementation (mutiplatform)
  • mvikotlin-logging - logging functionality (mutiplatform)
  • mvikotlin-timetravel - time travel feature (mutiplatform)
  • mvikotlin-extensions-reaktive - extensions set for Reaktive library (multiplatform)
  • mvikotlin-extensions-coroutines - extensions set for coroutines (multiplatform)
  • keepers - provides StateKeeper and InstanceKeeper API for state preservation and objects retaining
  • rx - a tiny module with abstractions over rx and coroutines (multiplatform)

Add required modules to your module`s build.gradle file:

implementation "com.arkivanov.mvikotlin:<module-name>:<version>"

Features

  • Multiplatform: Android, JVM, JavaScript, iosX64, iosArm64, macosX64, linuxX64
  • Does not depend on any reactive library or coroutines
  • Extensions for Reaktive library
  • Extensions for Coroutines
  • Multithreading friendly (freezable in Kotlin Native if needed)
  • Logging functionality with customizable logger and formatter
  • Time travel feature:
    • Multiplatform for all supported targets
    • Plug-and-play UI for Android
    • Plug-and-play UI for iOS (copy-paste from the sample app)
    • Export/import events for Android
    • IDEA and Android Studio plugin for Android apps
    • MacOS client application for iOS and macOS apps

Documentation

https://arkivanov.github.io/MVIKotlin

Sample project

The sample project is a todo list with details view.

  • Shared module using Reaktive is here
  • Shared module using coroutines is here
  • Sample Android application with both Reaktive and coroutines implementations, plus logging and time travel is here
  • Sample iOS application with Reaktive implementation only, plus logging and time travel is here
  • Sample JavaScript application with both Reaktive and coroutines implementations, plus logging and time travel is here

Author

Twitter: @arkann1985

If you like this project you can always Buy Me A Coffee ;-)

Watch video (time travel, logs, debug, etc.)

Debugging Android application with MVIKotlin

Debugging Android application with MVIKotlin

Debugging iOS application with MVIKotlin

Debugging iOS application with MVIKotlin

Debugging Android application with IntelliJ IDEA time travel plugin

Debugging Android application with IntelliJ IDEA time travel plugin

Debugging iOS application using MVIKotlin time travel client app

Debugging iOS application using MVIKotlin time travel client app

Comments
  • TimeTravel can't handle enums

    TimeTravel can't handle enums

    TimeTravel can't serialize Enum implementing JvmSerializable

    My Enum:

        enum class ConnectionStatus(val friendlyName: String): JvmSerializable {
            DISCONNECTED("Disconnected"),
            CONNECTING("Connecting"),
            CONNECTED("Connected"),
            AUTHENTICATED("Authenticated"),
        }
    

    Stacktrace:

    Exception in thread "AWT-EventQueue-0" java.lang.reflect.InaccessibleObjectException: Unable to make field private final java.lang.String java.lang.Enum.name accessible: module java.base does not "opens java.lang" to unnamed module @1aeda28e
    	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
    	at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
    	at java.base/java.lang.reflect.Field.checkCanSetAccessible(Field.java:178)
    	at java.base/java.lang.reflect.Field.setAccessible(Field.java:172)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$Companion.trySetAccessibleCompat(ValueParser.kt:271)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$Companion.accessEachField(ValueParser.kt:335)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$Companion.access$accessEachField(ValueParser.kt:252)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.toTreeDefault(ValueParser.kt:209)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.toTreeOther(ValueParser.kt:189)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.valueOfObject(ValueParser.kt:56)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.value(ValueParser.kt:23)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.getValue(ValueParser.kt:249)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.access$getValue(ValueParser.kt:7)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$toTreeDefault$1.invoke(ValueParser.kt:210)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$toTreeDefault$1.invoke(ValueParser.kt:209)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$Companion.accessEachField(ValueParser.kt:286)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser$Companion.access$accessEachField(ValueParser.kt:252)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.toTreeDefault(ValueParser.kt:209)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.toTreeOther(ValueParser.kt:189)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.valueOfObject(ValueParser.kt:56)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.value(ValueParser.kt:23)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.value$default(ValueParser.kt:21)
    	at com.arkivanov.mvikotlin.timetravel.proto.internal.data.value.ValueParser.parseValue(ValueParser.kt:15)
    	at com.arkivanov.mvikotlin.timetravel.server.TimeTravelServerImpl.analyzeEvent(TimeTravelServerImpl.kt:116)
    	at com.arkivanov.mvikotlin.timetravel.server.TimeTravelServerImpl.access$analyzeEvent(TimeTravelServerImpl.kt:19)
    	at com.arkivanov.mvikotlin.timetravel.server.TimeTravelServerImpl$onCommandReceived$$inlined$runOnMainThreadIfNotDisposed$1.invoke(TimeTravelServerImpl.kt:181)
    	at com.arkivanov.mvikotlin.timetravel.server.TimeTravelServerImpl$onCommandReceived$$inlined$runOnMainThreadIfNotDisposed$1.invoke(TimeTravelServerImpl.kt:153)
    	at io.github.dseelp.robotsystem.frontend.desktop.MainKt$timeTravelServer$1.invoke$lambda-0(Main.kt:21)
    	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:722)
    	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:716)
    	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
    	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
    
    bug 
    opened by DSeeLP 4
  • Add support for iosSimulatorArm64 target

    Add support for iosSimulatorArm64 target

    Please consider adding support for the iosSimulatorArm64 target.

    This currently fails due to the issue described in https://github.com/badoo/MVIKotlin/issues/200

    opened by GrahamBorland 3
  • hello. need some help

    hello. need some help

    hi, i encount some serous problem that i struggle for several days.

    I use MVIkotlin, its version is 2.0.4

    there is a SuspendExecutor, following is my own source.

    mmexport1663223464647 mmexport1663223468097

    my problem is i cant execute both collect meantime, everytime only the first collect is executed. i need to check what method the user choose to use my app, login as account or just visit, so i need to check these in executeAction

    im not sure whether you can understand what i say, thanks

    opened by MansonLuo 2
  • Handing finishing coroutine executor

    Handing finishing coroutine executor

    Is the any correct way to get know about finishing coroutine executor.

    For example, we have a some form and Save button. When user clicks Save button, we send intent to save this form on server side. Executor handles the intent and makes API call to server. After success response user is navigated to another page, on error user see error message.

    opened by serrg1994 2
  • todo-app-android and todo-app-ios dirs should be removed?

    todo-app-android and todo-app-ios dirs should be removed?

    It seems the directories sample/todo-app-{android,ios} were effectively split up between the coroutines and reaktive versions but a few files are left in the old locations.

    Most notably, I updated my git checkout and tried to load sample/todo-app-ios/todo-app-ios.xcodeproj unsuccessfully because its dependencies are now missing.

    opened by treitter 2
  • After making this repo as fork, search in the repository doesn't work

    After making this repo as fork, search in the repository doesn't work

    Not related to the library itself, but would be nice to have it as an issue.

    Hello @arkivanov , I've noticed that search in the repo doesn't work anymore. Even tried with suggested approach, still no success: https://docs.github.com/en/search-github/searching-on-github/searching-in-forks

    I tried this request also: https://github.com/search?q=isAssertOnMainThreadEnabled+repo%3Aarkivanov%2FMVIKotlin+fork%3Atrue

    Who knows how to search on the forked repository?

    opened by ultraon 2
  • Consider to not throw exceptions in Store.init

    Consider to not throw exceptions in Store.init

    Currently Store.init throws an error if the store is already initialized. This makes the initialization inconvenient if the store is retained via InstanceKeeper.

    enhancement 
    opened by arkivanov 1
  • Current support status for tvos target

    Current support status for tvos target

    Hello @arkivanov ,

    First of all I want to congratulate and thank you for all the hard work you put on this library. I've been using it the past few months with a multiplatform app that runs on JS, Android and iOS and I am really happy with the results so thanks so much for your contribution to the community!

    I was hoping to add tvos support to the application I was wandering what is the current support for the tvos target. I've seen that no artifacts are published to maven repository but checking the code of the repository and the code of the com.arkivanov.gradle.setup plugin that the tvos target is not configured by default but there are some bits of code indicating that may be configured (I've not checked the code deeply but I have seen the posibility of adding the targets through the tvosCompat() function of the plugin). Could I fork the project and try to setup the support the tvos locally and expect it to work or is disabled by default due to some other reason?

    Thank you again for your time and work!

    enhancement 
    opened by denislfernandez 1
  • All the sample links are dead

    All the sample links are dead

    The links to sample projects in the ReadMe are dead.

    Consider updating the doc to link the new sample projects, including maybe the one in compose-jb repository aswell.

    documentation 
    opened by benjdero 1
  • Update docs after 3.0.0 release

    Update docs after 3.0.0 release

    • Time Travel Client App is now packaged on CI for Linux and Windows, macOS can be packaged locally from sources
    • Time Travel IDEA plugin is able to connect to Darwin and JVM apps
    documentation 
    opened by arkivanov 1
  • Null Pointer exceptions in log when running unit tests

    Null Pointer exceptions in log when running unit tests

    We run unit tests in KMM on our stores which are using coroutines and when the test runs we see exceptions like this in the log:

    java.lang.NullPointerException
    	at com.arkivanov.mvikotlin.utils.internal.MainThreadAssert.getMainThreadId(MainThreadAssert.kt:9)
    	at com.arkivanov.mvikotlin.utils.internal.MainThreadAssertKt.isMainThread(MainThreadAssert.kt:24)
    	at com.arkivanov.mvikotlin.rx.internal.BaseSubject$1.invoke(BaseSubject.kt:13)
    	at com.arkivanov.mvikotlin.rx.internal.BaseSubject$1.invoke(BaseSubject.kt:13)
    	at com.arkivanov.mvikotlin.rx.internal.BaseSubject.subscribe(BaseSubject.kt:23)
    	at com.arkivanov.mvikotlin.main.store.DefaultStore.labels(DefaultStore.kt:74)
    	at com.arkivanov.mvikotlin.logging.store.LoggingStore.labels(LoggingStore.kt)
    

    This does not actually cause the tests to fail, but is annoying seeing this noise in the logs. It fails because we are not actually running on an Android device so there is no main looper. You have the isAssertOnMainThreadEnabled variable to disable maint thread assertions but it doesn't disable this check in BaseSubject.

    enhancement 
    opened by dalewking 1
  • "Used by" list

    It would be good to have a list of companies/users/projects where MVIKotlin is used. I suggest to stick to the following format, but feel free to omit/add/modify any details. ❤️

    Project name: <project name> Project type: production/pet/sample Company name: personal/<company name> Supported platforms: Android, JVM, Web, iOS, macOS, etc. Link (an open source repository or a web site): <link>

    opened by arkivanov 2
  • Update time travel docs

    Update time travel docs

    The plugin functionality is actually similar to the desktop client app, it can connect to Android, JVM and Darwin apps. Also there are typos, e.g. "All recording events will appear ...". Link: https://arkivanov.github.io/MVIKotlin/time_travel.html

    documentation help wanted good first issue 
    opened by arkivanov 2
Releases(3.0.2)
  • 3.0.2(Aug 18, 2022)

  • 3.0.0(Jul 13, 2022)

    ⚠️ This release is published without compatibility metadata variant - the IDE may flag MVIKotlin as unresolved if you are using Kotlin 1.6.20 or above. This is fixed in v3.0.1.

    What's new since v3.0.0-beta02

    • Reordered DSL generics (#36)
    • Replaced getMainThreadId stack trace with error message (#37)
    • Updated Kotlin to 1.7.1, Gradle to 7.4.2, AGP to 7.2.0, Essenty to 0.4.2, coroutines to 1.6.3 (#44, #46)
    • Added settings dialog to IDEA Time Travel Plugin (#41)
    • The Time Travel desktop client app is now built on CI, artifacts are attached to releases (for Windows and Linux only, please build from sources for macOS) (62b76fc691ad2db6fa076a8100c00f2aa0c0fe33)

    Release highlights since v2.0.4

    • Experimental Store DSL - see the docs
    • Used Essenty library, removed Lifecycle from mvikotlin module, deprecated keepers module
    • Late Store initialization (and ability to instantiate from background thread) - see the docs
    • Added Apple silicon targets
    • Added Time Travel client app for desktop, removed the native one for macOS, improved the Time Travel protocol
    • Added experimental Chrome DevTools extension for time travelling - see the docs
    • Introduced CoroutineExecutor and CoroutineBootstrapper, deprecated SuspendExecutor and SuspendBootstrapper
    • Removed previously deprecated InstanceKeeper and StateKeeper from the mvikotlin module, removed previously deprecated mvikotlin-extensions-androidx module
    • Allow duplicate store names in TimeTravelController. TimeTravelStoreFactory now doesn't need the fallback StoreFactory
    • Renamed Result to Message in Store
    • Renamed handleIntent and handleAction methods to executeIntent and executeAction respectively in Executor interface
    • Deprecated Android TimeTravelView
    • Refactored all samples
    • Some bug fixes and improvements
    Source code(tar.gz)
    Source code(zip)
    mvikotlin-time-travel-client-3.0.0-1.x86_64.rpm(83.23 MB)
    mvikotlin-time-travel-client_3.0.0-1_amd64.deb(68.31 MB)
    MVIKotlin.Time.Travel.Client-3.0.0.msi(78.17 MB)
  • 3.0.0-beta02(Apr 30, 2022)

    • Added experimental Store DSL (#30) - check out the updated docs
    • Removed ExperimentalCoroutinesApi annotations, because the used coroutines API is no longer experimental (#28)
    • Refactored all samples (#29)
    • Updated docs (#31, #32)
    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-beta01(Feb 10, 2022)

    • Added experimental Chrome DevTools extension for time travelling (#22, #24)
    • Renamed the isAutoInit argument of the StoreFactory.create methods to autoInit (#26)
    • Deprecated Android TimeTravelView (#23)
    • Fixed a crash where a Store is created on a non-main thread with the TimeTravelStoreFactory being used (#25)

    Breaking changes

    Deprecated Android TimeTravelView

    The Android TimeTravelView is now deprecated. The existing time travel clients (the IntelliJ IDEA plugin and the standalone desktop client) cover all the use cases, and even more. If you really need to use the TimeTravelView, please consider copy-pasting the code to your projects.

    Renamed isAutoInit argument

    The isAutoInit argument of the StoreFactory.create methods was renamed to autoInit. If you don't supply it explicitly, then the source compatibility should not be broken.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-alpha03(Dec 27, 2021)

    • Renamed handleIntent and handleAction methods to executeIntent and executeAction respectively in Executor interface (#12)
    • Renamed Result to Message in Store (#15)
    • Updated Kotlin to 1.6.10 and coroutines to 1.6.0 (#16)

    Breaking changes

    This release address necessary API changes towards the upcoming 3.0.0 release.

    Executor interface

    In the Executor interface the following methods were renamed:

    • handleIntent -> executeIntent
    • handleAction -> executeAction

    This brakes binary compatibility, but should not break source compatibility unless you have custom Executor interface implementations (like SuspendExecutor).

    Result is renamed to Message

    Now the Executor dispatches Messages, and not Results. The Reducer now also process Messages instead of Results. You can read about the rationale in the corresponding issue: #6. This change also breaks the binary compatibility, the source compatibility should not be broken in most of the cases. Checkout the documentation for more information and updated samples.

    Source code(tar.gz)
    Source code(zip)
  • 3.0.0-alpha02(Dec 19, 2021)

Owner
Arkadii Ivanov
Android developer. Passionate about Kotlin Multiplatform, MVI and reactive programming.
Arkadii Ivanov
Architecture Study with MVVM and MVI

Android-Architecture-Sample Android Architecture Study with MVVM and MVI Using DI(Hilt) + Retrofit + Coroutine + Moshi + AAC Stack 100% Kotlin + Corou

copin-danny 5 Jan 6, 2022
Kotlin Multiplatform Router for Android and iOS

A powerful Kotlin Multiplatform Router for Android and iOS Support I am happy to help you with any problem on gitter Feel free to open any new issue!

Sebastian Sellmair 343 Nov 16, 2022
MVU for Kotlin Multiplatform

Oolong Oolong is an Elm inspired Model-View-Update (MVU) implementation for Kotlin multiplatform. As the name implies, three core concepts comprise th

Oolong 288 Nov 29, 2022
Model-View-ViewModel architecture components for mobile (android & ios) Kotlin Multiplatform development

Mobile Kotlin Model-View-ViewModel architecture components This is a Kotlin Multiplatform library that provides architecture components of Model-View-

IceRock Development 638 Jan 2, 2023
Redux implementation for Kotlin (supports multiplatform JVM, native, JS, WASM)

Redux-Kotlin ![badge][badge-ios] A redux standard for Kotlin that supports multiplatform projects. Full documentation at http://reduxkotlin.org. Misso

Redux-Kotlin 301 Dec 25, 2022
A data-binding Presentation Model(MVVM) framework for the Android platform.

PLEASE NOTE, THIS PROJECT IS NO LONGER BEING MAINTAINED. As personal time contraints, I am currently unable to keep up. Please use official android da

RoboBinding open source 1.3k Dec 9, 2022
A full-featured framework that allows building android applications following the principles of Clean Architecture.

EasyMVP A powerful, and very simple MVP library with annotation processing and bytecode weaving. EasyMVP eliminates the boilerplate code for dealing w

null 1.3k Nov 19, 2022
Movie app that receives popular movies and allows the user to search for the specific movie through the Rest API with help of retrofit library &MVVM architecture.

MovieClue Millions of movies, TV shows and people to discover. Explore now Movie app that recieves popular movies and allow the user to search for spe

Shubham Tomar 6 Mar 31, 2022
Unidirectional Data Flow in Kotlin - Port of https://github.com/ReSwift/ReSwift to Kotlin

ReKotlin Port of ReSwift to Kotlin, which corresponds to ReSwift/4.0.0 Introduction ReKotlin is a Redux-like implementation of the unidirectional data

null 538 Dec 13, 2022
MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, Kotlin, navigation component, and so on...

MVVM RECIPE ANDROID APP Is an app where I show how to use MVVM, retrofit, dagger hilt, coroutine, liveData, kotlin, navigation component, and so on...

Isaias Cuvula 23 Dec 5, 2022
A sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern.

This repository contains a sample project in Kotlin to demonstrate AndroidX, MVVM, Coroutines, Hilt, Room, Data Binding, View Binding, Retrofit, Moshi, Leak Canary and Repository pattern

Areg Petrosyan 42 Dec 23, 2022
Android Clean Architecture💎 Base Project Android with Kotlin and MVVM applying clean architecture

Android Clean Architecture?? Base Project Android with Kotlin and MVVM applying clean architecture

Mina Mikhail 103 Dec 2, 2022
A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test.

TVMaze-Cache A sample to showcase Kotlin, MVVM, Koin, Coroutines, StateFlow, Room, WorkManager, Retrofit and Unit test. Features MVVM Architecture + R

Mohammadali Rezaei 25 Jul 21, 2022
📒Note taking app, MVVM with Google Architectural components Room, LiveData and ViewModel written in Kotlin, androidx libraries

?? MyNotes Note taking Android App using androidx libraries, MVVM with Google Architectural components Room, LiveData and ViewModel. Written in Kotlin

Akshat Bhuhagal 60 Dec 5, 2022
JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends.

JeTaxi is built on Clean Architecture-MVVM with Kotlin and follows modern android development trends. Also, It uses some of Jetpack and popular libraries. These are Kotlin Coroutine-Flow, kotlinx.serialization, Hilt, Compose, Accompanist, Retrofit2, OkHttp3, Chucker, MockWebServer, Truth.

Tolga Bolatcan 13 Nov 2, 2022
Android App using Kotlin, MVVM, ViewModel, LiveData, Coroutines, Room and DataBinding

Words Android App using Kotlin, MVVM, ViewModel, LiveData, Coroutines, Room and

Viacheslav Veselov 0 Jul 16, 2022
Nucleus is an Android library, which utilizes the Model-View-Presenter pattern to properly connect background tasks with visual parts of an application.

Nucleus Deprecation notice Nucleus is not under develpment anymore. It turns out that Redux architecture scales way better than MVP/MVI/MVVM/MVxxx and

Konstantin Mikheev 2k Nov 18, 2022
Moxy is MVP library for Android

Moxy This Moxy repository is deprecated and no longer supported. Please migrate to the actual version of the Moxy framework at Moxy communuty repo. De

Arello Mobile 1.6k Dec 28, 2022
A Model-View-Presenter / Model-View-Intent library for modern Android apps

Mosby A Model-View-Presenter and Model-View-Intent library for Android apps. Dependency dependencies { compile 'com.hannesdorfmann.mosby3:mvi:3.1.1

Hannes Dorfmann 5.5k Jan 5, 2023