Skip to content

theRealGetman/feature-manager

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Feature Manager for Flutter

License: MIT

Feature Manager allows you to hide unfinished or secret features from your users, or manage experiments that can be controlled from a remote data source or local settings.

If you want to use A/B testing or feature toggling with Firebase Remote Config, use Remote Config Feature Manager

Example Developer Preferences
Example 01 Example 02

Getting Started

Installation

Add the following to your pubspec.yaml:

dependencies:
  feature_manager: ^latest_version
  # Other dependencies

dev_dependencies:
  build_runner:
  feature_manager_generator: ^latest_version

Then run:

flutter packages get

Basic Usage

Creating Features with Code Generation

Starting from version 3.0.0, feature_manager supports code generation to simplify feature creation and management.

Steps to Use Code Generation:

  1. Add Annotations to Your Features

Create a Dart file (e.g., app_features.dart) and define your features using the provided annotations:

import 'package:feature_manager/annotations.dart';
import 'package:feature_manager/feature.dart';
import 'package:feature_manager/feature_manager.dart';

part 'features.g.dart';

@FeatureManagerInit()
class AppFeatures {
  AppFeatures({
    required this.textFeature,
    required this.booleanFeature,
    required this.doubleFeature,
    required this.integerFeature,
    required this.jsonFeature,
  });

  factory AppFeatures.instance() => _$AppFeatures();

  @FeatureOptions(
    key: 'dev-prefs-text-pref',
    remoteSourceKey: 'REMOTE-KEY-dev-prefs-text-pref',
    title: 'Text pref',
    description: 'This is text preference',
    defaultValue: 'Some default text',
  )
  final TextFeature textFeature;

  @FeatureOptions(
    key: 'dev-prefs-bool-pref',
    title: 'Toggle pref',
    description: 'This is toggle preference',
    defaultValue: false,
  )
  final BooleanFeature booleanFeature;

  @FeatureOptions(
    key: 'dev-prefs-double-pref',
    title: 'Number double pref',
    description: 'This is number double preference',
    defaultValue: 2.2,
  )
  final DoubleFeature doubleFeature;

  @FeatureOptions(
    key: 'dev-prefs-integer-pref',
    title: 'Number integer pref',
    description: 'This is number integer preference',
    defaultValue: 1,
  )
  final IntegerFeature integerFeature;

  @FeatureOptions(
    key: 'dev-prefs-json-pref',
    title: 'Json pref',
    description: 'This is json preference',
    defaultValue: {"value": "Json default value"},
  )
  final JsonFeature jsonFeature;
}
  • Annotations: Use the @FeatureManagerInit() annotation on the AppFeatures class to indicate that code should be generated.
  • Feature Fields: Annotate each feature field with @FeatureOptions() and provide the necessary parameters.
  • Factory Constructor: The factory AppFeatures.instance() returns an instance of the generated class _$AppFeatures().
  • Part Directive: The part 'features.g.dart'; directive tells Dart where to find the generated code.
  1. Run the Code Generator

Execute the following command to generate the feature classes:

flutter packages pub run build_runner build
  1. Use the Generated Features

Import the generated file and use the features in your code:

import 'features.dart';
// The generated part file is automatically included due to the 'part' directive.

void main() {
  final appFeatures = AppFeatures.instance();

  // Access individual features
  final textValue = appFeatures.textFeature.value;
  final isEnabled = appFeatures.booleanFeature.isEnabled;

  // Access all features using the extension
  for (final feature in appFeatures.values) {
    print('Feature key: ${feature.key}');
  }
}
  • Accessing Features: You can access each feature via the instance of AppFeatures.
  • Using the Extension: An extension AppFeaturesExt is generated to provide a values getter, which returns a list of all features.

Using Features

To check whether a feature is enabled using FeatureManager, you can create an instance via dependency injection (e.g., Provider, GetIt) or directly:

import 'package:feature_manager/feature_manager.dart';

final featureManager = FeatureManager();

final appFeatures = AppFeatures.instance();

// Check if a feature is enabled
final isEnabled = featureManager.isEnabled(appFeatures.booleanFeature);

Alternatively, since each feature provides an isEnabled property, you can directly access it:

final isEnabled = appFeatures.booleanFeature.isEnabled;

Modify feature values in DEBUG (develop) mode

To do it, you can simply open DeveloperPreferences screen in any part of your app. You should pass list of your features as parameter for this screen.

P.S. You should hide this button for production builds.

Navigator.of(context).push(
  MaterialPageRoute(
    builder: (BuildContext context) =>
      DeveloperPreferencesScreen(Features.values),
    ),
);

Note: Hide this screen or navigation option in production builds to prevent users from accessing development features.

Feature parameters

Parameter Default Description
key String required This key will be used to store value in local storage.
type FeatureType FeatureType.feature It can be used to separate local features and experiments driven by some remote provider.
title String required Title that will be used inside Developer Preferences Screen.
remoteSourceKey String Key from remote source.
description String Description that will be used inside Developer Preferences Screen.
defaultValue Object? Null Default value of the Feature. Will be returned by FeatureManager if stored value is Null
enum FeatureType { feature, experiment }

Contributions

Feel free to contact me ([email protected]) or create Pull Requests for this repository :)

About

Feature Manager plugin for flutter projects

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages