Note: This branch contains code for flavors, to use boilerplate without flavors checkout to withoutFlavors branch.
-
assets
-
It will be located at "project/assets"
-
This folder will keep all the local resources that we will use in our application. It can further contain subcategories like "fonts", "images" etc having the corresponding folders.
-
-
To make use of the contents of this folder we need to define it in pubspec.yaml.
-
lib
-
It will be located at "project/lib"
-
This is the most important folder in a flutter project, everything that we code will sit here in most cases, if we are not using any platform-specific or native coding in our flutter application.
-
"Here we will not have a main.dart file. We will have a folder named flavors, we will look into it in more detail in coming steps."
-
-
This boilerplate will contain following subcategories in lib folder:
-
constants
-
controllers
-
i18n
-
models
-
router
-
store
-
theme
-
utils
-
viewmodel
-
views
-
flavors
-
Let us understand one by one what each folder is going to do:
-
This folder will contain all the constants that we will be using in our application.
-
It can be subcategorized into categories like api constants, string constants, message constants, enums etc.
-
-
This folder will contain the code for all the network calls, in simpler language we can call it the "Network Layer" of our project.
-
Essentially, it will contain a base api class which contains the generic method for all kind of requests i.e. GET, POST, PUT, DELETE, PATCH, in this project we are using Dio for making API calls.
-
-
-
This folder will contain json for using localization in the project.
-
It can contain a json file for every language that we'll be using in the project.
-
-
-
This folder will contain the parsing models of every json object that we receive after a successful/unsuccessful API request.
-
It will contain a generic response class that will be used in the base API class we discussed earlier.
-
Note: While making a response/request model make sure to remove the methods that are not in use, like toJson(), fromJson() etc.
-
-
- This folder will contain our router class, that has all the navigation logic written as per Navigation 2.0 (route named navigation).
-
-
This folder will have any files or folders containing code for any local storage that we might use in our application.
-
It can have files for SQLite, Shared preferences, secure storage, hive database etc.
-
-
- This folder will contain files for colors, themes, textstyles etc that will be used in the project.
-
-
Utils folder will have folders like various helper functions, validation functions etc.
-
Helper functions can have any general function that we can use in the entire application.
-
Validation functions will contain validation logic for text inputs etc.
-
-
-
This folder will contain mostly all the business logic that will be used in the application.
-
We are using Provider for state management in the given boilerplate.
-
This will contain a generic viewmodel, which will have common functions or attributes like state variables, update UI methods etc for all the viewmodels.
-
All the viewmodels that we make will be extension of the BaseViewModel in order to use the common functions.
-
-
-
This folder will contain the UI element of the application.
-
This will further be categorized into screens and widgets.
-
Screen folder will contain the distinct screen UI.
-
Widgets folder will contain common UI elements that will be used in the entire application or entire module of the project.
-
-
-
While using flavors, we will make use of this folder.
-
It will contain one main_common.dart file that will have the code with MaterialApp, it is the main entry point of our project, but it won't have runApp() method called in here.
-
Now comes the interesting part, each flavor will have its own file, say prod environment will have a file main_prod.dart and here runApp() will be called by passing the class that we created in main_common.dart.
-
-
Using command
-
Simple flutter run won't work out in the case of flavors. We will need to call the following command to run our app.
-
flutter run --flavor flavor_name -t corresponding_main_flavor_file_path
-
E.g. flutter run --flavor qa -t lib/flavors/main_qa.dart
-
-
Via VS Code
-
In this boilerplate launch.json file has been configured with three flavors, prod, dev and qa.
-
So in the located section there will be option to choose from any flavor, as shown below
-
-
Creating Build via command
-
Simple flutter build apk won't work out in case of flavors. We will need to call the following command to build an android apk.
-
flutter build apk --release --flavor flavor_name -t corresponding_main_flavor_file_path or
-
flutter build apk --release --obfuscate --split-debug-info=build/app/outputs/symbols --flavor flavor_name -t corresponding_main_flavor_file_path
-
E.g. flutter build apk --release --flavor qa -t lib/flavors/main_qa.dart or
-
flutter build apk --release --obfuscate --split-debug-info=build/app/outputs/symbols --flavor qa -t lib/flavors/main_qa.dart
-
-
Adding/deleting flavors
-
iOS
-
Adding or removing flavors from iOS will take a few setup, let's see how we can add a new flavor or edit the existing one for iOS.
-
Open XCode for your project > Product > Scheme > Manage Scheme
-
- This will show all the existing flavors that we are using this boilerplate, we can delete any flavor from here if not required by clicking on "-" and can add a new one by clicking on "+".
- While adding a new flavor from here, make sure to select the target as "Runner" only.
- Once the scheme (flavor) is added we will need to make a few more changes.
- Go to Project Runner > Info & add debug, profile and release as per the name of the scheme. E.g. Debug-flavorname, Profile-flavorname & Release-flavorname.
- Go to Target Runner > Build Setting & change the display name of app as per different flavors, if required.
- Open XCode for your project > Product > Scheme > Edit Scheme and add the respective configuration file for the flavor.