A Boilerplate Project which adopts the concept of Clean Architecture and Modularization

  Flutter App

Flutter-Works Boilerplate

Table of Content

  • Overview
  • Getting Started
    • Requirements
    • Setup
  • Firebase Setup
    • Android
    • IOS
  • Change Package Name
  • Running/Debugger
    • 1. Dev Mode (Development)
    • 2. Staging Mode
    • 3. Production Mode
    • If User VS Code
  • Features
  • Libraries / Dependencies
  • Folder Structure
  • Module
    • List of Default Modules
      • Shared Modules:
      • Module Features:
    • Create Module
  • Global Config/Variable
    • Call Global Variable
  • Use of Translation/Localization
    • Create Item Translation
    • Generate Translation
    • Get Item Translation
    • Create Locale
    • Set Play Locale
  • Generate Icon Launcher
  • Generate Native Splash Screen

Overview

This repository is an Open-Source project intended for Boilerplate on Flutter that really supports your productivity, with lots of features that we have prepared instantly that can speed up your work process.

Screenshots

Theme12345
Dark
Light

Getting Started

Requirements

Here are some things you need to prepare before this Boilerplate setup:

  1. Flutter SDK Stable (Latest Version)  Install
  2. Android Studio  Install
  3. Visual Studio Code (Optional)  Install
  4. Darts  and  Flutter Extensions  :

Setup

To set up your project based on this boilplate, you need to do some of the steps you need to do. For a simple example of implementation, see the branch example

Here are the steps for setting up a Project with this Flutter-Works boilerplate:

Step 1:

In this step you need to download(cloning) the files from this repository to your local computer:

git clone http://github.com/kodingworks/flutter-works-boilerplate.git

Or

git clone git@github.com:kodingworks/flutter-works-boilerplate.git

Step 2:

The next step is to open the folder that has been downloaded / cloned to a cli application such as bashcmdterminal.

And then run this command to the console:

flutter pub get

Firebase Setup

Because this boilerplate uses a lot of technology from firebase, you need to configure it first before you run the application for the first time. Here’s an example/tutorial on how to setup firebase:

Android

  1. The first step to setup firebase on Android is to create your project first in the firebase console
  1. Download google-services.jsonaccording to their respective flavors and package names. Check Change Package Name
  1. Enable authentication via google in the firebase console.
  1. Create a sample remote config version

IOS

TODO: Implement Firebase IOS Setup Tutorial

Change Package Name

By default package names:

Prod: io.kodingworks Dev: io.kodingworks.dev Staging: io.kodingworks.staging

To change the package name, simply search for all io.kodingworks., then replace it with the new package name, for example: com.mycompany. .

Running/Debugger

In this boilerplate there are several flavorthat allow you to run several types, for example for mode pengembanganproduksi, and many more. This boilerplate provides boilerplate flavors for Android and IOS by default . Here are the flavor types that we have configured:

1. Dev Mode (Development)

This flavor is intended only for testing, and debugging during development. To run on this flavor you just run this command:

flutter run -t lib/main_dev.dart --flavor dev

2. Staging Mode

This flavor is for demo mode:

flutter run -t lib/main_staging.dart --flavor staging

3. Mode Prod (Production)

Pada flavor ini diperuntukkan hanya pada release mode (untuk digunakan oleh user beneran):

Saran: Pada flavor ini jangan diperuntukan untuk test, demo.

flutter run -t lib/main_staging.dart --flavor staging

Jika Pengguna VS Code

Jika Anda adalah pengguna VS Code sebagai alat/tool dalam pengembangan app ada Flutter gunakan launch config yang sudah kami sediakan tinggal pilih flavor apa yang Anda ingin jalankan.

Kelebihan dari menggunakan VS Code yaitu: Anda dapat melakukan breakpoint tiap line code lebih mudah dibanding menggunkan cli.

Features

FeatureAndroidIOS
Multiple Languageheavy_check_markheavy_check_mark
Dark Mode/Multiple Themesheavy_check_markheavy_check_mark
Google Analyticheavy_check_markheavy_check_mark
Firebase Perfomanceheavy_check_markheavy_check_mark
Firebase Remote Configheavy_check_markheavy_check_mark
Firebase Push Notificationheavy_check_markwarning
Firebase Authenticationheavy_check_markheavy_check_mark
Login With Googleheavy_check_markheavy_check_mark
Login With Applexwarning
Version Checkheavy_check_markheavy_check_mark

Library / Dependency

Pada boilerplate ini ada beberapa library yang kami tambahkan untuk menunjang produktifitas dalam pengerjaannya. Berikut daftar beberapa library yang sudah tersedia pada boilerplate ini berseta deskripsi dan versinya:

NameDeskripsiVersi
dartzDigunakan untuk Functional Programming.^0.9.2
dioSebagai library untuk mengatasi http request yang sangat beragam.^3.0.10
equatableUntuk mengatasi komparasi dari object.^1.2.6
flutter_blocSebagai library untuk mengatasi segala State Management yang sangat flexible.^6.1.2
formzDigunakan untuk mengatasi validasi Form pada State Management yang mudah dan reusable.^0.3.2
get_itLibrary yang berfungi untuk mengatasi Dependency Injection.^5.0.6
hiveSebagai DataBase utama yang mengatasi berbagai dynamic data, dengan performa yang sangat optimal.^1.4.4+1
image_pickerUntuk mengatasi pengambilan gambar dari camera maupun gallery.^0.6.7+22
rxdartUntuk mengatasi reactiveX untuk asynchronous programming^0.25.0
url_launcherUntuk mengatasi peluncuran berbagai URL/link ke berbagai aplikasi yang tersedia di App.^5.7.10
package_infoUntuk mengambil dari data native App sekarang seperti versi, nama aplikasi, dll.^0.4.3+4
firebase_authUntuk mengatasi authentikasi dari firebase.^0.20.0+1
firebase_coreLibrary utama dari Firebase SDK untuk Flutter^0.7.0
firebase_crashlyticsLibrary yang berfungsi untuk mencatat berbagai masalah error code, BUG, yang tersedia dalam App.^0.4.0+1
firebase_messagingUntuk mengatasi notifikasi yang dari firebase console.^8.0.0-dev.14
firebase_performanceUntuk mencatat performa aplikasi kita dan request http di berbagai device yang dikimkan ke Firebase Console.^0.5.0+1
firebase_remote_configUntuk mengambil data configurasi dari firebase console, dengan value yang dynamic.^0.6.0
google_sign_inMengatasi login melalui google berdasarkan dari firebase.^4.5.9

Folder Structure

flutter_modular/
┣ .vscode/
┃ ┗ launch.json
┣ android/
┣ assets/
┃ ┣ cfg/
┃ ┃ ┣ dev_env.json
┃ ┃ ┣ prod_env.json
┃ ┃ ┗ stagging_env.json
┃ ┣ fonts/
┃ ┗ images/
┣ features/
┃ ┣ auth/
┃ ┃ ┣ lib/
┃ ┃ ┣ test/
┃ ┃ ┗ pubspec.yaml
┃ ┣ home/
┃ ┃ ┣ lib/
┃ ┃ ┣ test/
┃ ┃ ┗ pubspec.yaml
┃ ┗ settings/
┃ ┃ ┣ lib/
┃ ┃ ┣ test/
┃ ┃ ┗ pubspec.yaml
┣ ios/
┣ launcher/
┃ ┣ ic_foreground.png
┃ ┣ ic_launcher.png
┃ ┗ logo_splash.png
┣ lib/
┃ ┣ app.dart
┃ ┣ flavors.dart
┃ ┣ main_dev.dart
┃ ┣ main_prod.dart
┃ ┣ main_staging.dart
┃ ┣ module.dart
┃ ┗ routes.dart
┣ shared/
┃ ┣ component/
┃ ┣ core/
┃ ┣ dependencies/
┃ ┣ l10n/
┃ ┗ preferences/
┣ test/
┣ analysis_options.yaml
┣ pubspec.yaml
┗ README.md

Module

Karena pada project boilerplate ini adalah bersifat modular, jadi tiap feature perlu dipecah jadi module sendiri-sendiri. Jadi ini sangat memungkinkan jika Anda bekerja bersama tim, proses pengerjaan kode jadi lebih mudah dan terstruktur karena tiap anggota bisa mengerjakan dengan fokus di module yang mereka kerjakan.

List Default Modules

Secara default ketika Anda menggunakan boilerplate ini, terdapat beberapa module yang sudah terpasang secara otomatis, berikut daftar module-module yang sudah tersedia:

Shared Module:

NameDescription
coreSebuah module yang memuat class, function globa dan inti
componentSebuah module yang memuat global component, yang sifatnya tidak merender untuk spesifik module tertentu
dependenciesSebuah module yang memuat beberapa global dependency/library yang dijadikan satu package
l10nSebuah module yang memuat data translasi
preferenceSebuah module yang memuat tentang macam-macam gaya aplikasi, dan yang berhubungan dengan UI(User Interface)

Features Module:

NameDescription
authSebuah module yang diperuntukan untuk mengatasi bagian authentikasi pada aplikasi
homeSebuah module yang diperuntukan untuk Home
profileSebuah module yang diperuntukan untuk Profile Management
settingsSebuah module yang diperuntukan untuk mengatasi berbagai fitur setting pada app

Create Module

Ketika Anda membuat fitur baru yang dimana fitur tersebut mampu berjalan dengan sendiri tanpa ketergantungan sekali dengan fitur lain, Anda bisa membuat module terpisah sebagai module fitur terbaru Anda. Berikut contoh cara setup module baru:

Step 1: Copy template module.

Untuk template module sudah tersedia yang berada di root folder dengan nama folder template_module. Copy folder template_module tersebut ke destinasi/lokasi module di letakkan. Jika module tersebut adalah feature maka taruh module tersebut di dalam folder /features.

├── features/

Step 2: Rename Nama Module.

Langkah selanjutnya yaitu Anda perlu ganti nama module sesuai dengan feture Anda. Misal jika module tersebut adalah fitur payment, maka:

Before:

├─ features/
│  └─ template_module/
│    └─ lib/
│      └─ name_module.dart

After:

├─ features/
│  └─ payment
│    └─ lib/
│      └─ payment.dart

Pada file lib/payment.dart:

Before:

// TODO: change name module
library module;

export 'src/data/data.dart';
export 'src/domain/domain.dart';
export 'src/module.dart';
export 'src/presentation/presentation.dart';

After:

library payment;

export 'src/data/data.dart';
export 'src/domain/domain.dart';
export 'src/module.dart';
export 'src/presentation/presentation.dart';

Pada file lib/src/module.dart:

Before:

import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';

// TODO: Change Your Name Module
class NameModule implements BaseModule {
  @override
  void inject(GetIt getIt) {
    // Data

    // Domain

    // Presentation
  }

  @override
  Map<String, Route> routes(RouteSettings settings) {
    return {
      // Routes data in module
    };
  }
}

After:

import 'package:core/core.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';

class PaymentModule implements BaseModule {
  @override
  void inject(GetIt getIt) {
    // Data

    // Domain

    // Presentation
  }

  @override
  Map<String, Route> routes(RouteSettings settings) {
    return {
      // Routes data in module
    };
  }
}

Pada file pubspec.yaml:

Before:

# TODO: change name module
name: module
description: A new Flutter package project.
version: 0.0.1
author: "My Name"
homepage: "https://example.com"

environment:
  sdk: ">=2.7.0 <3.0.0"
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  # TODO: UnComment & fix change path package
  # core:
  #   path: ../../shared/core
  # component:
  #   path: ../../shared/component
  # dependencies:
  #   path: ../../shared/dependencies
  # l10n:
  #   path: ../../shared/l10n
  # preferences:
  #   path: ../../shared/preferences
  

dev_dependencies:
  flutter_test:
    sdk: flutter
  effective_dart: ^1.3.0

flutter:

After:

name: payment
description: A new Flutter package project.
version: 0.0.1
author: "My Name"
homepage: "https://example.com"

environment:
  sdk: ">=2.7.0 <3.0.0"
  flutter: ">=1.17.0"

dependencies:
  flutter:
    sdk: flutter
  
  core:
    path: ../../shared/core
  component:
    path: ../../shared/component
  dependencies:
    path: ../../shared/dependencies
  l10n:
    path: ../../shared/l10n
  preferences:
    path: ../../shared/preferences

dev_dependencies:
  flutter_test:
    sdk: flutter
  effective_dart: ^1.3.0

flutter:

Step 3: Daftarkan module ke root project.

Untuk mendaftarkan module feature yang pernah kita buat itu wajib, karena jika tidak kita daftarkan besar kemungkinan akan terjadi error. Untuk mendaftarkannya lihat berikut contohnya:

Langkah pertama pasang module tersebut di pubspec.yaml pada root project.

dependencies:
  flutter:
    sdk: flutter
  
  ...

  payment: 
    path: features/payment
  
dev_dependencies:
...

Sesuaikan dengan lokasi module Anda, pada contoh diatas module berada di dalam folder /features maka pathnya adalah features/payment.

Kemudian buka file lib/module.dart, dan tambahkan class Module yang Anda buat tadi. contoh:

...

List<BaseModule> appModules = [
  AuthModule(),
  HomeModule(),
  SettingsModule(),
  PaymentModule(), // New Module
];

Pada contoh tersebut PaymentModule adalah module terbaru yang telah dibuat. Setelah selesai jalankan ulang aplikasi Anda.

Global Config/Variable

Semua konfigurasi yang sifatnya global di simpan berupa env yang pada kasus ini kami menyimpanya di folder assets/cfg/.

Didalam folder tersebut terdapat beberapa file konfigurasi yang sebelumnya tersedia yaitu:

  • dev_env.json
  • prod_env.json
  • stagging_env.json

Pada tiap item tersebut memuat konfig yang berbeda-beda berdasarkan dari nama flavornya, misa jika flavornya dev maka namanya dev_env.json.

Untuk format konfigurasinya kami simpan berupa format file dengan extensions json karena config json yang paling mudah dibaca oleh Flutter itu sendiri.

Berikut contoh yang ada di konfigurasi env nya:

{
    "base_url": "https://example.co.id/v2",
    "app_name": "App",
    "encrypt": "AlOp7lBkcFRdJnXFkGcBHwM9I9TJMMas",
    "version_name": "1"
}

Pada contoh diatas semua variable tersebut itu adalah variable global, maupun variable konfigurasi enable/disable fitur.

Note: Ketika ada perubahan dalam file konfigurasi, tidak dapat melakukan hot reload data, dan Anda wajib melakukan restart debug. Hal ini terjadi karena setiap konfigurasi itu di muat pada saat pertama kali peluncuran aplikasi, atau pada saat method main() pada dart dijalankan pertama kali.

Panggil Global Variable

Untuk memanggil Global Variable Anda perlu menggunakan class GlobalConfiguration dan class GlobalConfiguration adalah bagian dari module core. Berikut contoh penggunaanya:

import 'package:core/core.dart';
import 'package:dependencies/dependencies.dart';

....

final appName = GetIt.I<GlobalConfiguration>().getValue('app_name');

print(appName);
....

Penggunaan Translation/Localization

Untuk data translation berada pada module l10n yang letaknya di /shared/l10n. Semua data translasi pada app Anda dimuat di module ini. Secara default bahasa yang di dukung sudah 2, yaitu bahasa Indonesia dan English.

Create Item Translation

Untuk membuat item translasi Anda perlu generate dari kode arb ke dart. Tapi jagan khawatir pada boilerplate ini sudah tersedia fitur generate translasi, untuk data-data translasi Anda bisa cek di folder lib/l10n yang berada di module l10n, yang filenya berextension .arb. Untuk contohnya bisa lihat ini:

{
  "hello": "Hello World"
}

Jadi pada extension .arb format data sama persis dengan format .json jadi pastinya lebih familiar lagi. Dimana tiap item tersebut mempunyai key dan value. Pada contoh di atas "hello" adalah sebagai key dan "Hello World" adalah sebagai value.

  • key adalah sebagai nama variable yang akan digenerate
  • ‘value` adalah text yang akan di tampilkan tiap bahasa masing-masing

Note: jika membuat translasi pastika semua bahasa key itu ada di semua bahasa yang ada di folder lib/l10n

**Jika Ingin menambahkan param di translasi **

{ // intl_en.arb
  "hello": "Hello my name is {name}"
}
{ // intl_id.arb
  "hello": "Halo namaku adalah {name}"
}

Dimana pada tanda {} tersebut berarti ada input param jika dipanggil.

Note: Pastikan jika Anda menambahkan param/plural di item translasi Anda wajib menambahkanya di semua localization bahasanya

Generate Translation

Setiap kali ada perubahan sekecil apapun yang ada di folder lib/l10n yang berada di module l10n maka Anda perlu mengenerate ulang kode, supaya hasil kodenya bisa terbaru. Untuk mengenerate anda cukup gunakan perintah seperti ini:

./generate_l10n.sh

Get Item Translation

Jika ingin panggil item translasi Anda perlu import terlebih dahulu module l10n. Dan tiap pemanggilan translasi Anda perlu panggil main class nya yaitu S. Contoh:

import 'package:l10n/l10n.dart';

...
S.current.hello; // Hello World
...

Jika Ada param:

import 'package:l10n/l10n.dart';

...
S.current.hello('Flutter'); // Hello My Name is Flutter
...

Create Locale

Untuk membuat translasi yang mendukung bahasa lain, Anda perlu membuat file tambahan pada module l10n dan di folder ‘lib/l10n’. Dengan format:

intl_{language_code}.arb

Buat file dengan format seperti diatas, atau juga bisa mengcopy dari salah satu localization lain, dengan rename sesuai kode bahasanya.

Jangan lupa setelah membuat bahasa lain, Anda perlu generate ulang.

Set Main Locale

Untuk setting default bahasa apa yang digunakan, jika bahasa tersebut tidak/belum Anda dukung pada suatu negara maka Anda perlu custom confignya. Secara default config default locale di set dalam bahasa english, Jika ingin custom bisa cek di pubspec.yaml pada shared/l10n/pubspec.yaml. Untuk contoh confignya seperti ini:

flutter_intl:
  enabled: true
  main_locale: en

Pada contoh tersebut main_locale dengan value en, berarti en tersebut code bahasa yang berarti bahasa English. Selengkapnya cek di sini Untuk mengetahi daftar kode bahasa di seluruh dunia.

Generate Icon Launcher

Secara default di boilerplate ini sudah custom icon launchernya, tapi jika ingin custom sesuai dengan keinginan Anda sendiri, Anda perlu custom terlebih dahulu gambar icon-icon yang ingin Anda jadikan sebagai Icon Launcher. Secara default telah disediakan template ukuran icon, berada di folder /launcher.

Step 1:

Dan untuk konfigurasi nya berada di file pubspec.yaml pada root project. Berikut contoh konfignya:

flutter_icons:
  android: "ic_launcher"
  ios: true
  image_path_android: "launcher/ic_launcher.png"
  adaptive_icon_background: "#E67442"
  adaptive_icon_foreground: "launcher/ic_foreground.png"
  image_path_ios: "launcher/ic_launcher.png"

Untuk info lebih bisa lihat di pub.dev.

Step 2:

Dan untuk generete iconnya Anda perlu jalankan perintah seperti ini:

flutter pub run flutter_launcher_icons:main

Step 3:

Because flutter_launcher_iconsthis package generates launcher icons on Android only main, it has not yet reached per flavor item, so you need to manually reconfigure again for icon sets for each flavor on Android.

  1. Copy the folder reslocated in/android/app/main/res
  1. Paste and replace to your destination flavor folder.

Then restart your application.

Generate Native Splash Screen

More info look at pub.dev , and After generating copy the folder back resto each flavor item the same as generate icon_launcher.

Download Flutter-Works Boilerplate package source code on GitHub

https://github.com/kodingworks/flutter-works-boilerplate