Local Storage Manager

pub package License Flutter

A comprehensive and type-safe Flutter local storage manager package that provides a clean, abstract interface for various storage backends with detailed error handling and functional programming patterns.

Features

✨ Type-Safe Operations: Fully generic API with compile-time type safety 🎯 Clean Architecture: Abstract interface following dependency inversion principle πŸ›‘οΈ Robust Error Handling: Comprehensive failure types with detailed error information πŸ”„ Functional Programming: Either-style result types for elegant error handling πŸ“¦ Batch Operations: Efficient multi-key operations for better performance πŸ” Rich Query Methods: Advanced storage inspection and filtering capabilities πŸš€ Multiple Backends: Currently supports SharedPreferences with extensible architecture πŸ§ͺ Fully Tested: Comprehensive test coverage with example app πŸ“š Well Documented: Extensive documentation with usage examples πŸ’Ž Flutter Integration: Uses flutter_shared_utilities for safe serialization

Supported Storage Types

  • βœ… Primitive Types: String, int, double, bool
  • βœ… Collections: List<T>, Map<String, T>
  • βœ… Complex Objects: Any serializable object via JSON
  • βœ… Nullable Values: Full null safety support

Installation

Add this to your package's pubspec.yaml file:

dependencies:
  local_storage_manager: ^x.y.z

Then run:

flutter pub get

Quick Start

1. Basic Setup

import 'package:local_storage_manager/local_storage_manager.dart';

// Create and initialize the storage manager using the factory pattern
final storageManager = await SharedPreferencesStorageManager.create();

2. Basic Operations

// Save values with type safety
final stringResult = await storageManager.setValue<String>('username', 'john_doe');
final intResult = await storageManager.setValue<int>('user_age', 25);
final boolResult = await storageManager.setValue<bool>('is_premium', true);

// Handle results functionally
stringResult.fold(
  (failure) => print('Save failed: ${failure.message}'),
  (success) => print('Save successful: $success'),
);

// Retrieve values
final usernameResult = storageManager.getValue<String>('username');
final username = usernameResult.getOrElse('guest'); // With default value

// Or use the convenience method
final userAge = storageManager.getValueWithDefault<int>('user_age', defaultValue: 0);

3. Complex Objects

// Store complex objects
final userProfile = {
  'id': '123',
  'name': 'John Doe',
  'email': 'john@example.com',
  'preferences': {
    'theme': 'dark',
    'notifications': true,
  },
  'tags': ['developer', 'flutter'],
};

final result = await storageManager.setValue<Map<String, Object?>>(
  'user_profile',
  userProfile,
);

// Retrieve complex objects
final profileResult = storageManager.getValue<Map<String, Object?>>('user_profile');
final profile = profileResult.valueOrNull;

4. Batch Operations

// Save multiple values at once
final batchData = {
  'session_id': 'sess_123',
  'last_sync': DateTime.now().toIso8601String(),
  'app_version': '1.0.0',
};

final batchResult = await storageManager.setMultipleValues(batchData);

// Remove multiple keys
final keysToRemove = ['temp_data', 'cache_key', 'old_session'];
final removeResult = await storageManager.removeMultipleValues(keysToRemove);

// Get multiple values
final keys = ['username', 'user_age', 'is_premium'];
final multiResult = storageManager.getMultipleValues<Object>(keys);

Advanced Usage

Error Handling

The package provides comprehensive error handling through the StorageResult<T> type:

final result = await storageManager.setValue<String>('key', 'value');

// Pattern matching style
result.fold(
  (failure) {
    switch (failure.type) {
      case StorageFailureType.keyNotFound:
        print('Key not found: ${failure.key}');
        break;
      case StorageFailureType.conversionError:
        print('Type conversion failed: ${failure.message}');
        break;
      case StorageFailureType.serializationError:
        print('Serialization failed: ${failure.message}');
        break;
      // Handle other failure types...
    }
  },
  (success) => print('Operation successful'),
);

// Chaining operations
result
  .onSuccess((value) => print('Saved: $value'))
  .onFailure((failure) => logError(failure))
  .map((value) => value.toString().toUpperCase());

Storage Information

// Check storage status
final hasKey = storageManager.containsKey('username').getOrElse(false);
final isEmpty = storageManager.isEmpty().getOrElse(true);
final size = storageManager.getStorageSize().getOrElse(0);

// Get all keys and values
final allKeys = storageManager.getAllKeys().getOrElse(<String>[]);
final allValues = storageManager.getAllValues().getOrElse(<String, Object?>{});

// Pattern matching for keys
final userKeys = storageManager.getKeysMatching('user_*').getOrElse(<String>[]);

Custom Storage Implementation

Create your own storage backend by implementing the LocalStorageManager interface:

class CustomStorageManager implements LocalStorageManager {
  // Private constructor
  CustomStorageManager._();

  // Static factory method for async initialization
  static Future<CustomStorageManager> create() async {
    final instance = CustomStorageManager._();
    // Perform any async initialization here
    return instance;
  }

  @override
  Future<StorageResult<bool>> setValue<T>(String key, T value) async {
    // Your custom implementation
  }

  @override
  StorageResult<T?> getValue<T>(String key) {
    // Your custom implementation
  }

  // Implement other required methods...
}

API Reference

Core Methods

Method Description Returns
setValue<T>(String key, T value) Saves a value with type safety Future<StorageResult<bool>>
getValue<T>(String key) Retrieves a typed value StorageResult<T?>
getValueWithDefault<T>(String key, {required T defaultValue}) Gets value with fallback T
removeValue(String key) Removes a key-value pair Future<StorageResult<bool>>
containsKey(String key) Checks key existence StorageResult<bool>
clearAll() Clears all storage Future<StorageResult<bool>>

Batch Operations

Method Description Returns
setMultipleValues(Map<String, Object?> values) Saves multiple values Future<StorageResult<bool>>
removeMultipleValues(List<String> keys) Removes multiple keys Future<StorageResult<bool>>
getMultipleValues<T>(List<String> keys) Gets multiple values StorageResult<Map<String, T?>>

Storage Information

Method Description Returns
getAllKeys() Gets all stored keys StorageResult<List<String>>
getAllValues() Gets all key-value pairs StorageResult<Map<String, Object?>>
getStorageSize() Gets number of stored items StorageResult<int>
isEmpty() Checks if storage is empty StorageResult<bool>
hasValue(String key) Checks key has non-null value StorageResult<bool>
getKeysMatching(String pattern) Gets keys matching pattern StorageResult<List<String>>

Error Types

The package defines comprehensive failure types:

  • StorageFailureType.keyNotFound - Key doesn't exist
  • StorageFailureType.conversionError - Type conversion failed
  • StorageFailureType.serializationError - JSON serialization failed
  • StorageFailureType.accessDenied - Storage access denied
  • StorageFailureType.quotaExceeded - Storage quota exceeded
  • StorageFailureType.networkError - Network-related error
  • StorageFailureType.operationFailed - General operation failure
  • StorageFailureType.invalidKey - Invalid key format
  • StorageFailureType.invalidValue - Invalid value format
  • StorageFailureType.corruptedData - Data corruption detected
  • StorageFailureType.unknown - Unknown error

Example App

Check out the comprehensive example app in the /example folder that demonstrates:

  • βœ… Basic CRUD operations
  • βœ… Complex object storage
  • βœ… Batch operations
  • βœ… Error handling patterns
  • βœ… Storage management UI
  • βœ… Real-time operation logging

Testing

The package includes comprehensive tests covering:

  • Unit tests for all storage operations
  • Integration tests with real storage backends
  • Error handling scenarios
  • Edge cases and null safety
  • Performance benchmarks

Run tests with:

flutter test

Contributing

We welcome contributions! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Changelog

See CHANGELOG.md for details about changes in each version.

Support


Made with ❀️ for the Flutter community

Libraries

local_storage_manager
A comprehensive Flutter local storage manager package for your app.