currency_converter

Currency Converter App

A modern Flutter application for currency conversion with real-time exchange rates, historical data visualization, and offline support.

GitHub Flutter Dart


๐Ÿ“ฑ Screenshots

View Screens


๐Ÿ“ฅ Download APK

Download the latest release APK directly:

Download APK

Direct Link: Download APK

Note: Make sure to enable โ€œInstall from Unknown Sourcesโ€ in your Android settings before installing the APK.


๐Ÿ”— Repository

GitHub: https://github.com/mohamedbasha275/currency_converter


๐Ÿ“‹ Table of Contents


๐Ÿš€ Build Instructions

Prerequisites

Before building the project, ensure you have the following installed:

Setup Steps

  1. Clone the repository
    git clone https://github.com/mohamedbasha275/currency_converter.git
    cd currency_converter
    
  2. Install dependencies
    flutter pub get
    
  3. Generate native assets and icons
    flutter pub run flutter_launcher_icons
    flutter pub run flutter_native_splash:create
    
  4. Run the app

    For Android:

    flutter run
    

    For iOS (macOS only):

    flutter run -d ios
    
  5. Build release APK (Android)
    flutter build apk --release
    
  6. Build release IPA (iOS)
    flutter build ios --release
    

Additional Notes


๐Ÿ—๏ธ Architecture Pattern

Clean Architecture with BLoC Pattern

This application follows Clean Architecture principles combined with the BLoC (Business Logic Component) pattern for state management.

Architecture Layers

The project is organized into three main layers:

  1. Presentation Layer (presentation/)
    • UI components (Screens, Widgets)
    • State management using BLoC/Cubit
    • User interactions and UI logic
  2. Domain Layer (domain/)
    • Business logic and use cases
    • Repository interfaces (contracts)
    • Entity models
    • Independent of external frameworks
  3. Data Layer (data/)
    • Data sources (Remote API, Local Database)
    • Repository implementations
    • Data models and DTOs
    • External dependencies

Project Structure Example

lib/features/currency_converter/
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ datasources/          # API and local data sources
โ”‚   โ””โ”€โ”€ repositories/          # Repository implementations
โ”œโ”€โ”€ domain/
โ”‚   โ”œโ”€โ”€ repositories/          # Repository interfaces
โ”‚   โ””โ”€โ”€ use_cases/             # Business logic use cases
โ””โ”€โ”€ presentation/
    โ”œโ”€โ”€ manager/               # BLoC/Cubit state management
    โ”œโ”€โ”€ screens/               # Full screen widgets
    โ””โ”€โ”€ widgets/               # Reusable UI components

Justification for Clean Architecture

  1. Separation of Concerns
    • Each layer has a single, well-defined responsibility
    • Business logic is isolated from UI and data sources
    • Easy to understand and maintain
  2. Testability
    • Domain layer can be tested independently without UI or database
    • Use cases can be unit tested with mock repositories
    • Data layer can be tested separately from business logic
  3. Independence
    • Domain layer doesnโ€™t depend on Flutter or external libraries
    • Business rules remain unchanged when UI or data sources change
    • Framework-agnostic core logic
  4. Scalability
    • Easy to add new features following the same pattern
    • Clear boundaries between layers prevent code coupling
    • Supports team collaboration with clear module boundaries
  5. Maintainability
    • Changes in one layer donโ€™t affect others
    • Easy to locate and fix bugs
    • Code is self-documenting through structure

Justification for BLoC Pattern

  1. Reactive Programming
    • Stream-based state management provides reactive UI updates
    • Handles asynchronous operations elegantly
  2. Separation of Business Logic from UI
    • UI components are pure and testable
    • Business logic is centralized in BLoC/Cubit classes
  3. Predictable State Management
    • Unidirectional data flow
    • Easy to debug with BLoC observer
    • State changes are traceable
  4. Flutter Ecosystem Integration
    • Well-supported by Flutter team
    • Extensive community and resources
    • Works seamlessly with dependency injection (GetIt)

Dependency Injection

The project uses GetIt for dependency injection, which provides:


๐Ÿ–ผ๏ธ Image Loader Library

Cached Network Image (cached_network_image: ^3.3.1)

The application uses Cached Network Image for loading and caching currency flag images from network URLs.

Usage in the Project

The library is primarily used in the CurrencyFlag widget to display country flags:

CachedNetworkImage(
  imageUrl: url,
  width: size,
  height: size,
  memCacheWidth: 100,
  fit: BoxFit.cover,
  placeholder: (_, __) => Icon(Icons.flag_circle),
  errorWidget: (_, __, ___) => Icon(Icons.flag_circle),
)

Justification for Choosing Cached Network Image

  1. Automatic Caching
    • Images are automatically cached to disk and memory
    • Reduces network requests and improves performance
    • Works offline after initial load
  2. Memory Optimization
    • Built-in memory cache management
    • Configurable cache size limits
    • Prevents memory leaks and excessive memory usage
  3. Performance Benefits
    • Fast image loading from cache
    • Reduces bandwidth consumption
    • Improves app responsiveness
  4. User Experience
    • Placeholder widgets while loading
    • Error handling with fallback widgets
    • Smooth fade-in animations (configurable)
    • No flickering on image reloads
  5. Ease of Use
    • Simple API similar to Flutterโ€™s Image.network
    • Drop-in replacement with additional features
    • Well-documented and maintained
  6. Production Ready
    • Widely used in production Flutter apps
    • Actively maintained with regular updates
    • Handles edge cases (network errors, invalid URLs, etc.)
  7. Memory Cache Configuration
    • Supports memCacheWidth and memCacheHeight for memory optimization
    • Reduces memory footprint for large images
    • Essential for apps displaying many images (currency flags list)

๐Ÿ’พ Database

SQLite with sqflite (sqflite: ^2.3.0)

The application uses sqflite (SQLite for Flutter) as the primary local database solution.

Usage in the Project

The database is used to store currency information locally:

Database Helper Implementation

The project includes a CurrencyDatabaseHelper singleton class that manages:

Justification for Choosing sqflite

  1. Native SQLite Integration
    • Direct access to SQLite database engine
    • Full SQL support for complex queries
    • High performance for relational data
  2. Offline Support
    • Currency list available without internet connection
    • Improves user experience in low-connectivity scenarios
    • Reduces dependency on API availability
  3. Performance
    • Fast read/write operations
    • Efficient batch operations
    • Indexed queries for quick searches
    • Suitable for large datasets
  4. Data Persistence
    • Data survives app restarts
    • Reliable storage for critical app data
    • No data loss on app updates
  5. Flexibility
    • Supports complex queries (JOIN, WHERE, ORDER BY)
    • Easy to add new tables and relationships
    • Migration support for schema changes
  6. Flutter Ecosystem
    • Official Flutter plugin
    • Well-maintained and stable
    • Extensive documentation and community support
  7. Production Ready
    • Used by thousands of Flutter apps
    • Battle-tested in production environments
    • Regular security and performance updates

Shared Preferences (shared_preferences: ^2.5.4)

The application also uses Shared Preferences for simple key-value storage.

Usage in the Project

Shared Preferences is used for:

Justification for Using Shared Preferences

  1. Simplicity
    • Perfect for simple key-value pairs
    • No need for complex database setup
    • Easy to use API
  2. Performance
    • Faster than database for simple data
    • Minimal overhead for small data
    • Synchronous read operations
  3. Appropriate Use Case
    • Ideal for boolean flags (onboarding status)
    • Suitable for user preferences
    • Not overkill for simple settings
  4. Platform Native
    • Uses native storage mechanisms (NSUserDefaults on iOS, SharedPreferences on Android)
    • Reliable and platform-optimized

Combined Database Strategy

The project uses a hybrid approach:

This approach provides:


๐Ÿ“ Project Structure

lib/
โ”œโ”€โ”€ app_widgets/              # Shared app-wide widgets
โ”œโ”€โ”€ common/                   # Common UI components
โ”œโ”€โ”€ core/                     # Core functionality
โ”‚   โ”œโ”€โ”€ bloc_observer/        # BLoC observer for debugging
โ”‚   โ”œโ”€โ”€ di/                   # Dependency injection (GetIt)
โ”‚   โ”œโ”€โ”€ errors/               # Error handling
โ”‚   โ”œโ”€โ”€ extension/            # Dart extensions
โ”‚   โ”œโ”€โ”€ helper_functions/     # Utility functions
โ”‚   โ”œโ”€โ”€ navigation/           # Routing and navigation
โ”‚   โ”œโ”€โ”€ resources/            # App constants, colors, themes
โ”‚   โ”œโ”€โ”€ shared_preferences/   # SharedPreferences wrapper
โ”‚   โ””โ”€โ”€ use_cases/            # Base use case class
โ”œโ”€โ”€ features/                 # Feature modules
โ”‚   โ”œโ”€โ”€ currency_converter/   # Currency conversion feature
โ”‚   โ”œโ”€โ”€ currency_list/        # Currency list feature
โ”‚   โ”œโ”€โ”€ historical_rates/     # Historical rates feature
โ”‚   โ”œโ”€โ”€ onboarding/          # Onboarding screens
โ”‚   โ””โ”€โ”€ home_screen.dart     # Main home screen
โ”œโ”€โ”€ main.dart                 # App entry point
โ””โ”€โ”€ main_helper.dart         # App initialization helpers

๐Ÿ“ฆ Key Dependencies

State Management

Dependency Injection

Networking

Database & Storage

Image Loading

UI & Utilities

Error Handling

Testing


๐Ÿ”ฎ Future Enhancements (Optional โ€“ Time Permitting)

The following features are optional enhancements and are not required for the core functionality of the task. They are listed to demonstrate the appโ€™s scalability and future potential if additional time is available.

๐ŸŒ™ Dark Mode

๐ŸŒ Internationalization (i18n)

๐Ÿงช Widget Tests & Integration Tests

๐Ÿ’ฐ Cryptocurrency Support

โญ Favorite Currencies

๐Ÿ“Š Currency Tracking (Monthly / Yearly)

๐Ÿ“ Note

These enhancements are intentionally separated from the main scope of the task. Thanks to the use of Clean Architecture and BLoC, these features can be added incrementally without impacting the existing implementation.


๐Ÿ“ Notes


๐Ÿงช Testing

The project includes comprehensive unit tests covering all layers of the application. For detailed testing documentation, see:

๐Ÿ“– Test Documentation

Quick Test Commands

# Run all tests
flutter test

# Run tests with coverage
flutter test --coverage

# Run tests for a specific feature
flutter test test/features/currency_converter/

Test Coverage


๐Ÿ‘จโ€๐Ÿ’ป Development

For development guidelines and contribution instructions, please refer to the projectโ€™s development documentation.


๐Ÿ“„ License

This project is open source and available for educational purposes.


Built with โค๏ธ using Flutter

Repository: https://github.com/mohamedbasha275/currency_converter