easy_shared_preferences library

Easy Shared Preferences

A game or app settings oriented wrapper API for shared_preferences (with cache), type-safe settings framework for Flutter applications with automatic validation, change notifications, and modular design.

Note: The same warnings and caveats apply as with the original shared_preferences package, such as not using it for sensitive data or large datasets.

Quick Start

1. Create Store and Manager

1.1. Global/Static Usage

import 'package:easy_shared_preferences/easy_shared_preferences.dart';
void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize global settings early in main()
  await GlobalSettings.initialize([
    // Game settings group
    GroupConfig(
      key: 'game',
      items: [
        BoolSetting(key: 'soundEnabled', defaultValue: true),
        DoubleSetting(
          key: 'volume',
          defaultValue: 0.8,
          validator: (value) => value >= 0.0 && value <= 1.0,
        ),
        IntSetting(
          key: 'difficulty',
          defaultValue: 1,
          validator: (value) => value >= 1 && value <= 3,
        ),
      ],
    ),
    // UI settings group
    GroupConfig(
      key: 'ui',
      items: [
        StringSetting(
          key: 'theme',
          defaultValue: 'light',
          validator: (value) => ['light', 'dark', 'auto'].contains(value),
        ),
        BoolSetting(key: 'showAnimations', defaultValue: true),
        IntSetting(
          key: 'fontSize',
          defaultValue: 14,
          validator: (value) => value >= 12 && value <= 24,
        ),
      ],
    ),
  ], enableLogging: true);
  // Now you can use GlobalSettings anywhere in your app
  // For example, to get a setting value:
  bool soundEnabled = GlobalSettings.getBool('game.soundEnabled');
  runApp(MyApp());
}

1.2. Instance Usage

import 'package:easy_shared_preferences/easy_shared_preferences.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // Create the settings store and manager
  final store = SettingsStore();
  final settings = Settings(store: store);

  // Define your settings groups
  final gameSettings = SettingsGroup(
    key: 'game',
    items: [
      BoolSetting(key: 'soundEnabled', defaultValue: true),
      DoubleSetting(
        key: 'volume',
        defaultValue: 0.8,
        validator: CommonValidators.percentage.validate,
      ),
      IntSetting(key: 'difficulty', defaultValue: 1),
    ],
    store: store,
  );

  final uiSettings = SettingsGroup(
    key: 'ui',
    items: [
      StringSetting(
        key: 'theme',
        defaultValue: 'light',
        validator: EnumValidator<String>(['light', 'dark', 'auto']).validate,
      ),
      BoolSetting(key: 'notifications', defaultValue: true),
    ],
    store: store,
  );

  // Register and initialize
  settings.register(gameSettings);
  settings.register(uiSettings);
  await settings.init();

  runApp(MyApp());
}

2. Use Your Settings

// Read settings
bool soundEnabled = settings.getBool('game.soundEnabled');
double volume = settings.getDouble('game.volume');
String theme = settings.getString('ui.theme');

// Write settings
await settings.setBool('game.soundEnabled', false);
await settings.setDouble('game.volume', 0.5);
await settings.setString('ui.theme', 'dark');

// Batch operations
await settings.setMultiple({
  'game.soundEnabled': false,
  'game.volume': 0.3,
  'ui.theme': 'dark',
});

// Change callbacks
settings.addChangeCallback((key, oldValue, newValue) {
  print('Setting $key changed from $oldValue to $newValue');
});

// Don't forget to dispose when done!
settings.dispose();

Advanced Usage

Validation

Settings support optional validation using built-in validator classes:

final volumeSetting = DoubleSetting(
  key: 'volume',
  defaultValue: 0.5,
  validator: CommonValidators.percentage.validate, // 0.0 to 1.0
);

final themeSetting = StringSetting(
  key: 'theme',
  defaultValue: 'light',
  validator: EnumValidator<String>(['light', 'dark', 'auto']).validate,
);

final emailSetting = StringSetting(
  key: 'email',
  defaultValue: '',
  validator: CommonValidators.email.validate,
);

final passwordSetting = StringSetting(
  key: 'password',
  defaultValue: '',
  validator: CompositeValidator<String>.and([
    LengthValidator(minLength: 8, maxLength: 50),
    RegexValidator(r'\d', customDescription: 'Must contain at least one digit'),
  ]).validate,
);

Change Notifications

Listen to setting changes with streams:

gameSettings['soundEnabled']?.stream.listen((enabled) {
  print('Sound ${enabled ? 'enabled' : 'disabled'}');
  updateAudioEngine(enabled);
});

uiSettings['theme']?.stream.listen((theme) {
  print('Theme changed to: $theme');
  updateAppTheme(theme);
});

Non-Configurable Settings

Some settings can be marked as read-only:

final systemSetting = BoolSetting(
  key: 'debugMode',
  defaultValue: false,
  userConfigurable: false, // Cannot be modified by user code
);

Reset Operations

// Reset a single setting
await settings.resetSetting('game.volume');

// Reset an entire group
await settings.resetGroup('ui');

// Reset all settings
await settings.resetAll();

Classes

BoolSetting
A setting that stores boolean (true/false) values.
CommonValidators
Predefined validators for common use cases.
CompositeValidator<T>
Combines multiple validators using logical operations.
DoubleSetting
A setting that stores double-precision floating-point values.
EasySettings
Settings manager providing centralized access to all setting groups.
EnumValidator<T>
Validates that values are within a predefined set of allowed values.
EspLogger
Global logger instance for the Easy Shared Preferences framework.
GlobalSettings
Global settings manager that provides convenient app-wide access to settings.
GroupConfig
Configuration for a settings group used in GlobalSettings initialization.
IntSetting
A setting that stores integer numeric values.
LengthValidator
Validates string length constraints.
ListContentValidator
Validates the content of items within a string list.
ListLengthValidator
Validates string list length constraints.
RangeValidator<T extends Comparable>
Validates that numeric values fall within a specified range.
RegexValidator
Validates strings against a regular expression pattern.
Serializable
Setting<T>
Abstract base class for all setting types.
SettingFactory
SettingsGroup
A comprehensive settings group that manages related settings with persistence, initialization, and type-safe access.
SettingsStore
A store that manages the underlying SharedPreferences with caching.
SettingValidator<T>
Abstract base class for all built-in validators.
StringListSetting
A setting that stores lists of string values.
StringSetting
A setting that stores string text values.
ValidationResult<T>
Represents the result of a validation operation.

Enums

SettingType
Enum for supported setting value types.

Mixins

TypedSettingAccess
Interface for type-safe setting access with performance optimizations.

Extensions

SettingTypeInfo on TypedSettingAccess
Extension to provide performance hints and type information.

Typedefs

ValidationErrorHandler<T> = T? Function(String settingKey, dynamic invalidValue, String validationError)
Type definition for validation error recovery handlers.

Exceptions / Errors

SettingNotConfigurableException
Exception thrown when attempting to modify a non-configurable setting.
SettingNotFoundException
Exception thrown when a requested setting is not found.
SettingRecoveryException
Exception thrown when a setting value cannot be recovered after validation failure.
SettingsNotReadyException
Exception thrown when attempting to access settings before initialization.
SettingValidationException
Exception thrown when a setting value fails validation.