Whether you are new to flutter or you are an expert or an engineer in Flutter something that you will want to give a thumbs up to is a reusable codebase packed as a template to be used for whatever app you would be building or maintaining. While researching on Github almost a year ago I came across ICAPPS' flutter template repository. I normally like using the advanced search on Github to find whatever stuff am looking for.
Features of the ICAPPS Flutter Template
Dependency Injection (injectable/get it)
Network Layer (dio)
Network Logging (niddler, dio)
View Models (provider)
Translations (icapps translations)
Json Serialization (json_serializable)
Different Environments (dev, beta, alpha, prod)
Themes
Navigator
Linting (flutter analyze)
Local Storage (drift, shared preferences)
Tests (mockito, flutter test)
As soon as you get a deep dive into this template you will not take long to notice these smart tools all over the code base to make your coding smooth:
Annotations (retrofit, injectable, drift) - refer to documentation and comments that may be found on code logic. Annotation is typically ignored once the code is executed or compiled. Throughout the code, you will encounter annotations from the retrofit, injectable or drift packages
Provider State Management - Provider is a wrapper around InheritedWidget to make them easier to use and more reusable.
Modularisation - emphasizes separating the functionality of your app code into independent, interchangeable modules, such that each contains everything necessary to execute only one aspect of the desired functionality. You can see this well illustrated in the screenshot below
1. Dependency Injection
Dependency Injection (DI) is a design pattern that allows you to decouple your application's components and make them more testable, maintainable, and reusable. The template has employed 2 packages which are get_it and to help you with dependency injection.
a) Get_it package
The get_it
package provides a simple yet powerful service locator that allows you to register and retrieve instances of your application's dependencies. The package is based on a singleton pattern, which means that there is only one instance of the service locator that can be accessed throughout the application. You can use the registerSingleton
method to register a singleton instance of a class or the registerFactory
method to create a new instance every time it is requested.
b) Injectable package
The injectable
package builds on top of get_it
and provides a more convenient way to register and inject dependencies using annotations. With injectable
, you can annotate your classes and their constructors with @Injectable
and @factoryMethod
annotations respectively. This allows the package to automatically generate the necessary code to register and retrieve the dependencies using the get_it
package.
In the ICCAPS Flutter template, the get_it
and injectable
packages are used extensively to manage dependencies between different components of the application, such as the view, business logic, and data access layers. For example, the UserRepository
class, which is responsible for managing user data, is registered as a singleton using get_it
. Similarly, the AuthBloc
class, which handles authentication-related logic, is injected with the UserRepository
dependency using the @Injectable
annotation. Overall, the get_it
and injectable
packages provide a powerful and flexible way to implement dependency injection in your Flutter application, making it easier to write and maintain high-quality code.
2. Network Layer
The dio package in Flutter is a powerful library that allows you to make HTTP requests to web servers, RESTful APIs, or any other HTTP-based service. The package supports various features such as interceptors, authentication, and request cancellation. It is a popular choice among Flutter developers because of its simplicity, flexibility, and performance.
In the ICCAPS Flutter template, the network layer is responsible for handling all network-related operations in the application. It is built using the dio package, which makes it easy to perform HTTP requests and handle responses. The network layer is divided into different classes and functions, each with a specific purpose.
The ApiService
class is responsible for handling all API requests. It contains methods that correspond to the different endpoints of the API, such as login, registration, and fetching data. Each method uses the Dio
instance to make the HTTP request and return the response. The Dio
instance is created in the ApiClient
class, which sets up the base URL, headers, and other configurations for the HTTP client.
The network layer also includes interceptors that are used to modify requests and responses. For example, the AuthInterceptor
adds the user's access token to the request headers, ensuring that the user is authorized to access protected endpoints. Similarly, the ResponseInterceptor
intercepts the response and checks for errors or invalid data.
Overall, the dio package and the network layer in the ICCAPS Flutter template provide a robust and efficient way to handle HTTP requests and responses in a Flutter application. It abstracts away many of the low-level details of HTTP networking and allows developers to focus on building their application's features.
3. Network Logging
Network logging is the process of logging and analyzing network requests and responses in your application. In the ICCAPS Flutter Template, you will find 2 packages used to implement that.
a) Niddler Package
The niddler
package is a network debugger that allows you to inspect and modify network traffic between your application and the server. It provides a client and a server component, where the client is integrated into your application, and the server is installed on your development machine. The client and server communicate over a WebSocket connection, allowing you to capture and analyze all network traffic in real-time.
In the template, the niddler
package is used to log and debug network requests and responses. It is integrated into the ApiClient
class, which is responsible for handling all HTTP requests using the dio
package. The ApiClient
class creates a Dio
instance and adds an interceptor that logs the request and response data using the niddler
package.
b) Dio Package
The dio
package is a powerful HTTP client library that allows you to make HTTP requests and handle responses. It supports various features such as interceptors, authentication, and request cancellation. In the ICCAPS Flutter template, the dio
package is used in conjunction with the niddler
package to log network requests and responses.
Overall, the niddler
and dio
packages provide a powerful and convenient way to log and debug network traffic in your Flutter application. It makes it easier to identify and fix issues related to network communication and ensure that your application is performing as expected.
4. View Models
The ICAPPS Flutter template uses the provider
package for state management and implements a view model architecture to separate the presentation logic from the UI layer.
The provider package is a popular state management library that provides a simple and efficient way to manage state in a Flutter application. It uses the InheritedWidget and InheritedModel widgets to propagate state changes down the widget tree, allowing widgets to access and update shared state.
In the template, the provider
package is used to manage the state of the application, such as user authentication and data loading. The application uses a variety of providers, including ChangeNotifierProvider
, FutureProvider
, and StreamProvider
, to provide different types of state to the UI layer.
To separate the presentation logic from the UI layer, the ICAPPS Flutter template implements a view model architecture. The view model is a class that contains the presentation logic for a particular screen or component. It receives input from the UI layer, performs the necessary operations, and updates the state of the application through the providers.
The view models are implemented as classes that extend the ChangeNotifier
class provided by the provider
package. This allows the view models to notify the UI layer of any state changes using the notifyListeners()
method. The UI layer then updates itself based on the new state provided by the providers.
Overall, the provider
package and the view model architecture provide a powerful and efficient way to manage state and presentation logic in a Flutter application. It makes it easier to write and maintain high-quality code, and provides a better separation of concerns between the different layers of the application.
5. Translations
The icapps_translation package is used in the ICAPPS Flutter template for implementing translations in a Flutter application.
It provides a simple yet powerful way to manage translations and localization in your application. It allows you to define translation keys and their corresponding translations in a YAML file.
It supports multiple locales, allowing you to provide translations for different languages and regions.
It is used to manage translations for the application's UI components, such as buttons, labels, and error messages.
It provides a
TranslationService
class that is responsible for loading and providing translations for the application. The class uses theflutter_localizations
package to manage the different locales supported by the application.It provides a translation widget to help the template use translations in the UI layer. The
Translation
widget takes a translation key as input and automatically updates the UI with the corresponding translation based on the current locale.
The template also provides a convenient way to switch between different locales using a LanguageSelector
widget. The LanguageSelector
widget allows the user to select their preferred language and updates the current locale accordingly. Overall, the icapps_translation
package provides a simple and efficient way to manage translations and localization in a Flutter application. It makes it easier to support different languages and regions, and provides a better user experience for non-native speakers.
That is it for this one see you in the next article (Part 2)
Don't fail to Follow me here on Hashnode and On
Twitter @ JacksiroKe | Linked In Jack Siro | Github @ JacksiroKe