This is an Android application developed for the SWORD Health code challenge. It displays a list of cat breeds from TheCatAPI, allowing users to search, view details, and manage their favorite breeds.
The following features were implemented to meet the challenge requirements:
- Breed List: Displays a paginated list of cat breeds with their image and name.
- Search: A search bar allows filtering the list by breed name.
- Favorites: Users can mark and unmark breeds as favorites from both the list and detail screens.
- Favorites Screen: A dedicated screen shows only the breeds marked as favorite.
- Average Lifespan: The favorites screen displays the calculated average lifespan of all favorite breeds.
- Detail Screen: A screen showing detailed information about a selected breed, including its origin, temperament, and description.
- Navigation: The Jetpack Navigation Component is used to handle all screen navigation.
The project went beyond the basic requirements by incorporating the following best practices and technologies:
- MVVM Architecture: The presentation layer follows the official MVVM pattern.
- Jetpack Compose: The entire UI is built declaratively using Jetpack Compose.
- Unit Test Coverage: The domain and presentation layers (UseCases and ViewModels) have unit test coverage.
- Offline Functionality: The app uses a Room database as a local cache, allowing it to work offline and providing a seamless user experience.
- Error Handling: Network and database operation failures are handled gracefully, and users are notified via
Snackbars
without interrupting the user experience. - Efficient Pagination: The main list is paginated using the Paging 3 library with a
RemoteMediator
for a robust offline-first strategy. - Modular Design: The application is architected into multiple Gradle modules to enforce separation of concerns and improve build times.
The architecture was designed with a focus on scalability, maintainability, and modern practices.
-
Architecture: The project follows the MVVM (Model-View-ViewModel) pattern, heavily influenced by Clean Architecture principles. This creates a clear separation between the UI (Compose), Presentation (
ViewModel
), Domain (UseCase
), and Data (Repository
) layers. -
Modularization: The codebase is split into the following modules to enforce separation of concerns:
:app
: The main application module, responsible for integrating all features and handling top-level navigation.:core
: Contains the core data and domain logic, including the repository, use cases, database, network client, and domain models.:core_ui
: Holds shared and reusable Jetpack Compose components.:feature_*
: Self-contained feature modules (e.g.,:feature_breeds
,:feature_favourites
).
-
Data Layer: The Repository pattern is used to implement a Single Source of Truth (SSOT).
- Room is used as the local database.
- Retrofit is used as the network client to communicate with TheCatAPI.
- A
RemoteMediator
from the Paging 3 library orchestrates the synchronization between the API and the Room cache, ensuring a robust offline-first experience.
-
State Management: State is managed in the ViewModels and exposed to the UI using Kotlin
StateFlow
, ensuring a Unidirectional Data Flow (UDF) and predictable state updates. -
Dependency Injection: Hilt is used for dependency injection, decoupling components, simplifying their lifecycle management, and making the codebase easier to test.
- Clone the repository.
- Create a
local.properties
file in the root directory of the project. - Add your API key from TheCatAPI to the file:
API_KEY="YOUR_API_KEY_HERE"
- Open the project in a recent version of Android Studio and run the
app
configuration.
- Complete UI Test Coverage: Finalize the E2E test suite to cover all user flows.
- UI Animations: Add subtle animations and transitions to improve the user experience.