Konfigurasi Development dan Production dengan Flutter

Melanjutkan artikel Membuat App Flutter yang Sesuai dengan Desain kali ini kita akan belajar bagaimana kah membuat konfigurasi aplikasi mobile / smartphone dengan pengaturan development dan production ? Di flutter kita bisa menggunakan flavors untuk konfigurasi tersebut. 

Konfigurasi flavors di Android

Buka project prototype_app

Kita akan mengubah beberapa struktur aplikasi.

Buat file app.dart
Tambahkan code seperti berikut :

//  Created by Handoyo on 13/04/20.
//  Copyright © 2020 belajaraplikasi.com. All rights reserved.

import 'package:flutter/material.dart';
import 'package:prototype_app/login_page.dart';

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: LoginPage(title: 'Flutter Demo Home Page'),
    );
  }
}

Buat file config.dart
Tambahkan code seperti berikut :

//  Created by Handoyo on 13/04/20.
//  Copyright © 2020 belajaraplikasi.com. All rights reserved.

import 'package:flutter/material.dart';

enum Flavor { DEV, PROD }

class FlavorConfig {
  final Flavor flavor;
  final String name;
  static FlavorConfig _instance;

  factory FlavorConfig({
    @required Flavor flavor,
  }) {
    _instance ??= FlavorConfig._internal(flavor, flavor.toString());
    return _instance;
  }

  FlavorConfig._internal(this.flavor, this.name);
  static FlavorConfig get instance => _instance;

  static bool isProduction() => _instance.flavor == Flavor.PROD;
  static bool isDevelopment() => _instance.flavor == Flavor.DEV;
}

Buat file login_page.dart
Tambahkan code seperti berikut :

//  Created by Handoyo on 13/04/20.
//  Copyright © 2020 belajaraplikasi.com. All rights reserved.

import 'package:flutter/material.dart';

class LoginPage extends StatefulWidget {
  LoginPage({Key key, this.title}) : super(key: key);
  final String title;
  @override
  _LoginPageState createState() => _LoginPageState();
}

class _LoginPageState extends State<LoginPage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: SingleChildScrollView(
        child: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.only(left: 20, right: 20, top: 161),
              child: Text(
                'PROTOTYPE',
                style: TextStyle(
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                  color: Color(0xFF219653),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 20, right: 20, top: 73),
              child: TextField(
                decoration: InputDecoration(
                  hintText: 'Email',
                  hintStyle: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.bold,
                    color: Color(0xFF4F4F4F),
                  ),
                  enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Color(0xFF219653)),
                  ),
                  contentPadding: EdgeInsets.only(top: 10),
                ),
              ),
            ),
            Padding(
              padding: const EdgeInsets.only(left: 20, right: 20),
              child: TextField(
                decoration: InputDecoration(
                  hintText: 'Password',
                  hintStyle: TextStyle(
                    fontSize: 14,
                    fontWeight: FontWeight.bold,
                    color: Color(0xFF4F4F4F),
                  ),
                  enabledBorder: UnderlineInputBorder(
                    borderSide: BorderSide(color: Color(0xFF219653)),
                  ),
                  contentPadding: EdgeInsets.only(top: 20),
                  suffixIcon: Padding(
                    padding: const EdgeInsets.only(top: 10),
                    child: Icon(Icons.visibility_off, color: Color(0xFF4F4F4F)),
                  ),
                ),
              ),
            ),
            SizedBox(height: 32),
            Padding(
              padding: const EdgeInsets.only(left: 20, right: 20),
              child: Container(
                width: MediaQuery.of(context).size.width,
                height: 45,
                decoration: BoxDecoration(
                  color: Color(0xFF27AE60),
                  borderRadius: BorderRadius.circular(5),
                  boxShadow: [
                    BoxShadow(
                      color: Color.fromRGBO(0, 0, 0, 0.25),
                      blurRadius: 2,
                      spreadRadius: 1,
                      offset: Offset(0, 2),
                    ),
                  ],
                ),
                child: FlatButton(
                  onPressed: () {},
                  child: Text(
                    'Login',
                    style: TextStyle(
                      color: Color(0xFFF2F2F2),
                      fontSize: 14,
                      fontWeight: FontWeight.bold,
                    ),
                  ),
                ),
              ),
            ),
            SizedBox(height: 32),
          ],
        ),
      ),
    );
  }
}

Ubah file main.dart
Ubah code seperti berikut :

//  Created by Handoyo on 03/04/20.
//  Copyright © 2020 belajaraplikasi.com. All rights reserved.

import 'package:flutter/material.dart';
import 'package:prototype_app/app.dart';
import 'package:prototype_app/config.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  FlavorConfig(
    flavor: Flavor.PROD,
  );
  runApp(MyApp());
}

Buat file main_dev.dart
Tambahkan code seperti berikut :

//  Created by Handoyo on 13/04/20.
//  Copyright © 2020 belajaraplikasi.com. All rights reserved.

import 'package:flutter/material.dart';
import 'package:prototype_app/app.dart';
import 'package:prototype_app/config.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();
  FlavorConfig(
    flavor: Flavor.DEV,
  );
  runApp(MyApp());
}

Ubah di folder android/app/build.gradle
Ubah code seperti berikut :

    signingConfigs {
        release {}
    }

    buildTypes {
        release {
            // TODO: Add your own signing config for the release build.
            // Signing with the debug keys for now, so `flutter run --release` works.
            signingConfig signingConfigs.release
        }
    }

    flavorDimensions "flavors"
    productFlavors {
        dev {
            dimension "flavors"
            applicationIdSuffix ".dev"
            resValue "string", "app_name", "Prototype-dev"
        }
        prod {
            dimension "flavors"
            resValue "string", "app_name", "Prototype"
        }
    }

Ubah di folder android/app/src/main/AndroidManifest.xml
Ubah seperti berikut :

android:label="@string/app_name"

Ubah konfigurasi .vscode/launch.json

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Flutter",
            "request": "launch",
            "type": "dart",
            "args": [
                "--flavor",
                "dev",   //--- Ubah prod/dev
                "--target",
                "lib/main_dev.dart" //--- Ubah lib/main.dart / lib/main_dev.dart
            ]
        }
    ]
}

Tekan F5 untuk run aplikasi.

Next selanjutnya konfigurasi di iOS
Sekian dan terima kasih.
Happy coding 🙂

2 Comments

  1. gan saya ada error di @string/app_name
    Error: Duplicate resource
    solusinya gimana ya?

    1. itu kemungkinan ada tag xml yang sama di AndroidManifest.xml
      duplicate tag

      Terima kasih sudah berkunjung 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *