control_config 1.4.0-beta.2
control_config: ^1.4.0-beta.2 copied to clipboard
Wrapper around shared_preferences
control_config #
control_config is a control_core module that provides a robust and reactive layer over shared_preferences. It simplifies managing user preferences and configuration settings by offering type-safe access and automatic change notifications.
This library is ideal for:
- Persisting user settings (e.g., dark mode, language, custom preferences).
- Storing application configuration flags.
- Providing reactive access to preference changes throughout your app.
Features #
- Seamless Integration: Designed to work effortlessly with
control_core's dependency injection system. - Type-Safe Preferences: Set and get
bool,String,int,double, and evendynamic(JSON) values safely. - Reactive Preference Models:
PrefModelallows you to observe changes to individual preference keys. - Simplified Access:
PrefsProvidermixin for easy access toControlPrefsfrom any class. - Modular Setup:
ConfigModulefor integrating preferences into your application'sControlFactoryinitialization.
Installation #
Add control_config to your pubspec.yaml file:
dependencies:
control_config: ^2.0.0
Setup #
Recommended Setup #
Integrate ConfigModule into your Control.initControl() call. This is typically done in your main() function.
import 'package:control_core/core.dart';
import 'package:control_config/config.dart';
import 'package:flutter/widgets.dart'; // Required for binding initialization.
void main() async {
// Required by shared_preferences before it can be used.
WidgetsFlutterBinding.ensureInitialized();
Control.initControl(
modules: [
ConfigModule(), // This will automatically initialize SharedPreferences
],
);
// onReady ensures that all module initializations are complete.
await Control.factory.onReady();
print('Control System and Preferences are ready!');
// Example of using PrefsProvider after setup
final settings = UserSettings();
settings.username = 'Alex';
print('Username from settings: ${settings.username}');
}
Standalone Setup #
You can also initialize control_config without the full Control.initControl ceremony. This is useful for smaller apps or tests.
import 'package:control_config/config.dart';
import 'package:control_core/core.dart';
import 'package:flutter/widgets.dart';
void main() async {
// Required by shared_preferences before it can be used.
WidgetsFlutterBinding.ensureInitialized();
// This initializes ControlFactory with just the ConfigModule.
await ConfigModule.standalone();
// onReady ensures that the module is fully initialized.
await Control.factory.onReady();
print('Preferences are ready for standalone use!');
// Now you can use PrefsProvider
final prefs = PrefsProvider.instance;
prefs.setBool('is_first_launch', false);
print('Is first launch: ${prefs.getBool('is_first_launch')}');
}
Usage #
1. Accessing Preferences with PrefsProvider #
Mix PrefsProvider into your classes for convenient access to ControlPrefs. This is useful for business logic classes that need to read or write multiple preference values.
import 'package:control_config/config.dart';
import 'package:control_core/core.dart';
class UserSettings with PrefsProvider {
// Directly access preferences via the 'prefs' getter.
String get username => prefs.get('username', defaultValue: 'Guest')!;
set username(String value) => prefs.set('username', value);
bool get darkMode => prefs.getBool('dark_mode', defaultValue: false);
set darkMode(bool value) => prefs.setBool('dark_mode', value);
}
void demonstrateSettings() {
final settings = UserSettings();
print('Initial dark mode: ${settings.darkMode}');
settings.darkMode = true;
print('Updated dark mode: ${settings.darkMode}');
}
2. Reactive Preferences with PrefModel #
PrefModel creates an observable wrapper around a single preference key. It extends ChangeNotifier, so you can listen for changes, making it perfect for reactive business logic.
import 'package:control_config/config.dart';
import 'package:control_core/core.dart';
// Create PrefModel instances for specific preference keys.
final darkModePref = PrefModel.boolean('dark_mode', defaultValue: false);
final sub = darkModePref.subscribe((value) => print('Dark mode enabled: $value'));
3. Storing and Retrieving Custom Data (JSON) #
You can store and retrieve complex objects by providing get and set converter functions to PrefModel.data.
import 'package:control_config/config.dart';
class AppUser {
final String id;
final String name;
AppUser({required this.id, required this.name});
Map<String, dynamic> toJson() => {'id': id, 'name': name};
factory AppUser.fromJson(Map<String, dynamic> json) => AppUser(
id: json['id'] as String,
name: json['name'] as String,
);
}
// Create a reactive PrefModel for the AppUser object.
final currentUserPref = PrefModel.data<AppUser>(
'current_user',
(json) => AppUser.fromJson(json), // Getter: from JSON to AppUser
(user) => user?.toJson(), // Setter: from AppUser to JSON
);
void manageUserSession() {
// Save a user. This automatically converts to JSON and saves.
final user = AppUser(id: '123', name: 'Alex');
currentUserPref.value = user;
// Retrieve the user. This automatically reads the JSON and converts it back.
final savedUser = currentUserPref.value;
print('Saved user: ${savedUser?.name}'); // Prints: "Saved user: Alex"
}