Skip to content

Latest commit

 

History

History
78 lines (55 loc) · 4.29 KB

README.md

File metadata and controls

78 lines (55 loc) · 4.29 KB

Vision

The project will initially focus on building Compose-first Android only app, with long-term goal of supporting Kotlin Multiplatform with minimal code changes. Thus, any library which has KMP support will be preferred over android specific alternatives.

Architecture

The project will be divided into 3 layers

  • data - Responsible for handling the network, database & other sources of data storage, including an in-memory cache
  • domain - Responsible for all the business logic around data retrieval, caching, transformation, etc.
  • presentation - Responsible for User Interface of the app

Project follows api-impl modules pattern for the faster build times and facilitating fake implementations. Every non-app module depends on the :api module which only contains public interface and model classes. :app module in the end glues all the :impl modules to build the demo/prod apks. This way, any changes in the :impl module invalidates cache of only the updated module and app module, keeping incremental build times in check.

Libraries used

Coming from the traditional android background, Jetpack ViewModel is the most intuitive library for maintaining the presentation logic & state management. It can be easily scoped at Activity / Fragment / Jetpack NavGraph level using hilt. Recently, it started supporting Kotlin Multiplatform as well. Despite all of this, it lacks a good architecture specifically designed for Jetpack Compose. Circuit on the other hand, is compose-first, multiplatform library with really nice abstraction for State, UDF, Navigation, surviving configuration changes and DI. At current stage, a KMP support from a 3rd party library is more promising than androidx equivalents as we never know when the priorities would turn the table.

Project required a simple wrapper class to encapsulate API errors. While this might sound like premature optimization, constructing Exception object is expensive operation due its construction of stacktrace. Furthermore, it's recommended not to use Exceptions for the flow control (ref) We can't control external libraries from creating exceptions, but it can be avoided in the custom error handling. kotlin-result library is primarily considered for 2 reasons:

  • It's decoupling from native Exception/Thorwable classes
  • Reduced runtime overhead with 0 allocations on happy path

kotlin-inject, is kotlin-first, multiplatform, compile-time DI framework with very similar APIs to dagger. Since this project mainly focuses on performance & multiplatform capabilities, kotlin-inject suits very well here

Since this a sample app with dummy data, security is not our primary concern. But if it comes for free, with minimal efforts, it's always welcome. Bytemask masks secret strings for the app in the source code making it difficult to extract from reverse engineering.

Multiplatform way of sharing the local strings with compose friendly API. It has type-safe API for parameterized strings and with its code first approach, we can even load these strings dynamically from the API.

Coil has become de-facto image loading library, built using kotlin coroutines and even supports kotlin multiplatform.

Best way to maintain version catalog is to keep it sorted, clean & up-to-date. This library does all of this for you

A Gradle plugin that guards against unintentional dependency changes. It surfaces dependency changes due to transitive dependencies, allows maintaining deny-list of libraries that should never be shipped to production and generates a baseline file that can be version controlled