Skip to content

Repository files navigation

BMI Calculator – Kotlin Multiplatform (KMP)

A simple BMI (Body Mass Index) Calculator built using Kotlin Multiplatform (KMP) with:

  • Jetpack Compose for Android
  • SwiftUI for iOS
  • Shared MVVM architecture using StateFlow

This project demonstrates how to build a real-world cross‑platform app with clean architecture and proper state management.


📱 Features

  • Input weight (kg) and height (cm)

  • BMI calculation using standard formula

  • Validation for empty and invalid inputs

  • BMI category detection:

    • Underweight
    • Normal
    • Overweight
    • Obese
  • Color‑coded BMI result

  • Shared business logic between Android & iOS


🏗 Architecture Overview

This app follows MVVM with Unidirectional Data Flow.

UI (Compose / SwiftUI)
        ↓ Intent
Shared ViewModel (KMP)
        ↓
StateFlow<BmiUiState>
        ↓
UI observes & renders

Why this architecture?

  • Immutable state
  • Predictable UI behavior
  • Easy testing
  • Platform‑independent business logic

🧩 Modules

BMI/
 ├── androidApp/        → Android app (Jetpack Compose)
 ├── iosApp/            → iOS app (SwiftUI)
 └── shared/            → Shared KMP module

🔁 Shared Module (KMP)

Key Components

  • BmiViewModel – handles logic & state
  • BmiUiState – immutable UI state
  • StateFlow – reactive state updates

Example State

data class BmiUiState(
    val weight: String = "",
    val height: String = "",
    val bmiResult: BmiResult? = null,
    val error: String? = null
)

🤖 Android (Jetpack Compose)

  • Observes StateFlow using collectAsState()
  • Fully declarative UI
  • Color‑coded BMI output
val state by viewModel.uiState.collectAsState()

🍎 iOS (SwiftUI)

Important Concepts Used

  • ObservableObject for ViewModel wrapper
  • @Published for UI updates
  • @MainActor for thread safety
  • Manual Binding to avoid mutating Kotlin state directly
@Published var state: BmiUiState?

State updates are dispatched via ViewModel functions, not direct mutation.


🔐 Validation Rules

  • Weight must be > 0
  • Height must be > 0
  • Non‑numeric input is rejected
  • Error messages shown in UI

🎨 BMI Color Coding

Category Color
Underweight Blue
Normal Green
Overweight Orange
Obese Red

🧪 Formula Used

BMI = weight (kg) / (height (m) * height (m))

📦 Dependencies

Shared Module

  • Kotlin Coroutines
  • StateFlow

Android

  • Jetpack Compose

iOS

  • SwiftUI

🚀 How to Run

Android

  1. Open project in Android Studio
  2. Select androidApp
  3. Run on emulator or device

iOS

  1. Open iosApp.xcodeproj in Xcode
  2. Select simulator
  3. Run

🎯 Learning Outcomes

This project helps you understand:

  • Kotlin Multiplatform basics
  • Sharing ViewModels across platforms
  • StateFlow ↔ SwiftUI integration
  • Immutable state handling
  • Clean MVVM architecture

🔮 Possible Enhancements

  • Unit conversion (kg/lbs, cm/ft)
  • Save BMI history
  • Charts & analytics
  • Dependency Injection (Koin)
  • Unit tests

📄 License

MIT License


👨‍💻 Author

Manabendu

Built as a learning‑oriented KMP sample project 🚀

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages