HoangNguyen0403 / mvvm_architecture

Mvvm architecture template for Flutter
6 stars 1 forks source link
flutter mobile

mvvm_architecture

A base Flutter application with mvvm architecture

FVM Installation

https://fvm.app/docs/getting_started/installation

Getting Started

Configure Firebase Multi Flavor

Step 1 : Install Firebase CLI with npm : "npm install -g firebase-tools"

https://firebase.google.com/docs/cli#install-cli-mac-linux

Step 2 : Login to firebase account : "firebase login"

Step 3 : Install FlutterFire CLI with this command : "dart pub global activate flutterfire_cli"

Step 4 : Configure multi flavor with:

Run command "flutterfire configure -i packageName -a packageName -o lib/firebase/firebaseoptions{flavor}.dart" for each flavor.

Dev: "flutterfire configure -i com.vmo.c3FlutterTemp.dev -a com.vmo.c3FlutterTemp.dev -o lib/firebase/firebase_options_dev.dart"

Staging: "flutterfire configure -i com.vmo.c3FlutterTemp.staging -a com.vmo.c3FlutterTemp.staging -o lib/firebase/firebase_options_staging.dart"

Production: "flutterfire configure -i com.vmo.c3FlutterTemp -a com.vmo.c3FlutterTemp -o lib/firebase/firebase_options.dart"

Other configure:

Documentation at : https://firebase.google.com/docs/flutter/setup?platform=ios

Configuration Environment Running

Step 2 : Create new Configuration with build flavor value is :

Command need to run before run app

Build APK

Build IPA without archive on Xcode

Project architecture (MVVM Architecture)

Why

What

  1. UI - Repository.
  2. UI layer consist of
  1. Repository layer consist of

Project Structure

project
|--.fvm                                              # fvm config using for project
|   |--fvm_config.json                               # config file
|--android                                           # android project dir
|--assets                                            # application all assets
|   |--images                                        # application image assets
|   |--fonts                                         # application font assets
|--ios                                               # ios dir
|--lib                                               # main project dart lib entry point
|   |--config                                        # configuration for project
|   |   |--app_config.dart                           # config enum flavor and baseURL (development, staging, production)
|   |   |--colors.dart                               # config for color
|   |   |--navigation_util.dart                      # config navigation key and nested navigation key
|   |   |--styles.dart                               # config for text styles
|   |   |--theme.dart                                # config for theme for project
|   |--core                                          # core project include string extension, int extension, double extension,... 
|   |   |--string.dart                               # string extension function
|   |   |--double.dart                               # double extension function
|   |--firebase                                      # firebase config that auto generated by Firebase CLI
|   |--repositories                                  # repositories layer for mvvm architecture 
|   |   |--login                                     # login feature folder
|   |   |   |--models                                # login model request and response folder 
|   |   |   |--login.dart                            # export file for import in other place
|   |   |   |--login_api.dart                        # api abstract class on retrofit
|   |   |   |--login_api.g.dart                      # api generate class on retrofit
|   |   |   |--login_repository.dart                 # repository class for login feature
|   |   |--utils                                     # utils for data layer
|   |   |   |--exceptions                            # custom exception for repository layer
|   |   |   |--share_pref_manager.dart               # Share preferences manager class (include share preferences key enum)
|   |--ui                                            # ui layer for mvvm architecture 
|   |   |--common                                    # common widget or common screen
|   |   |--login                                     # login ui layer
|   |   |   |--bloc                                  # login bloc for whole login screen
|   |   |   |--ui                                    # ui folder for login feature
|   |   |   |   |--login_screen.dart                 # login ui frame
|   |   |   |   |--widgets                           # widgets folder for nested widget in login feature
|   |   |   |--login_route.dart                      # login route class define BlocProvider for Bloc class of login feature
|   |--utils                                         # utility folder for project
|   |   |--di                                        # dependencies injection registration for project
|   |   |--multi-languages                           # localization for project, using easy_localization and google sheet generator csv
|   |   |--route                                     # route config for project, include generateRoute and route define all screen of project
|   |   |--session_utils.dart                        # session utility for project like getAccessToken or something using common most
|   |--main.dart                                     # main config Material App and runApp
|--test                                              # unit test
|--web
|--.gitignore                                        # ignore file of git
|--fastlane                                          # config ci/cd using fastlane
|--README.md                                         # ReadMe for this project
|--analysis_options.yaml                             # lint rule configuration, config rule here
|--.gitlab-ci.yml                                    # config ci/cd for gitlab
|--pubspec.yaml                                      # dart package management file, add new dependencies here
|--.setup_app.sh                                     # Script to set up app before run app
|--.setup_env_config.sh                              # Script to set up environment variable to display on ci/cd
|--.setup_fastlane.sh                                # Script to set up fastlane config before run ci/cd
|--..build_android.sh                                # Script to build android on local

Injections

  1. We are using get_it for injections. It is fun because we can start the service locator and use it everywhere when needed because they are injected at top-level in main.dart.
  2. Only use it upon initialization
getIt.registerSingleton<LoginBloc>(LoginBloc(
    loginUseCase: LoginUseCase(getIt<LoginRepositoryImpl>()),
  ));

and use it on route

BlocProvider<LoginBloc>(
    create: (_) => getIt.get<LoginBloc>(),
),

for reusing the BLoC,

BlocProvider.value(
    value: getIt.get<PumpsBloc>(),
)

for usage (in Widgets), always use

context.boc<PumpsBloc>().add(AddPumps());

instead of

getIt.get<PumpsBloc>().add(AppPumps());

For non widget usage, manually inject the object on initialization.

Localization

We are using Easy Localization to handle multi-languages. Using Google Sheet Generator on cloud will take less effort for change and update key and value. Only need update in google sheet file. (Using only one way, csv or json)

Google sheet sample on this project : "https://docs.google.com/spreadsheets/d/1SpiJWFRfJaIRnzpEc0mJ2WaaI9JYlz8jKBPduAPzdXE/edit#gid=1013756643"

Step to set-up google sheet :

Step to setup json file in project :

Step to use multi-languages import in code:

Link library : https://pub.dev/packages/easy_localization Link plugin generate csv from google sheet : https://github.com/Hoang-Nguyenn/easy_localization_generator

Json parsing / serialization

This project is implementing json_serializable. It use build_runner to generate files. If you make a change to these files, you need to re-run the generator using build_runner:

flutter pub run build_runner build

generator using build_runner and remove conflict file :

flutter pub run build_runner build --delete-conflicting-outputs

Dio Interceptor

Assets

Adding new Assets

Remove Asset(s)

How to change version number and version code :

Step to change package name

Using fastlane