Stockage
Introduction
Nylo Website v7 fournit un systeme de stockage puissant via la classe NyStorage. Il utilise flutter_secure_storage en arriere-plan pour stocker les donnees de maniere securisee sur l'appareil de l'utilisateur.
import 'package:nylo_framework/nylo_framework.dart';
// Save a value
await NyStorage.save("coins", 100);
// Read a value
int? coins = await NyStorage.read<int>('coins'); // 100
// Delete a value
await NyStorage.delete('coins');
Enregistrer des valeurs
Enregistrez des valeurs en utilisant NyStorage.save() ou le helper storageSave() :
// Using NyStorage class
await NyStorage.save("username", "Anthony");
await NyStorage.save("score", 1500);
await NyStorage.save("isPremium", true);
// Using helper function
await storageSave("username", "Anthony");
Enregistrer dans Backpack simultanement
Stockez a la fois dans le stockage persistant et dans le Backpack en memoire :
await NyStorage.save('auth_token', 'abc123', inBackpack: true);
// Now accessible synchronously via Backpack
String? token = Backpack.instance.read('auth_token');
Lire des valeurs
Lisez des valeurs avec conversion de type automatique :
// Read as String (default)
String? username = await NyStorage.read('username');
// Read with type casting
int? score = await NyStorage.read<int>('score');
double? rating = await NyStorage.read<double>('rating');
bool? isPremium = await NyStorage.read<bool>('isPremium');
// With default value
String name = await NyStorage.read('name', defaultValue: 'Guest') ?? 'Guest';
// Using helper function
String? username = await storageRead('username');
int? score = await storageRead<int>('score');
Supprimer des valeurs
// Delete a single key
await NyStorage.delete('username');
// Delete and remove from Backpack too
await NyStorage.delete('auth_token', andFromBackpack: true);
// Delete multiple keys
await NyStorage.deleteMultiple(['key1', 'key2', 'key3']);
// Delete all (with optional exclusions)
await NyStorage.deleteAll();
await NyStorage.deleteAll(excludeKeys: ['auth_token']);
Cles de stockage
Organisez vos cles de stockage dans lib/config/storage_keys.dart :
final class StorageKeysConfig {
// Auth key for user authentication
static StorageKey auth = 'SK_AUTH';
// Keys synced on app boot
static syncedOnBoot() => () async {
return [
coins.defaultValue(0),
themePreference.defaultValue('light'),
];
};
static StorageKey coins = 'SK_COINS';
static StorageKey themePreference = 'SK_THEME_PREFERENCE';
static StorageKey onboardingComplete = 'SK_ONBOARDING_COMPLETE';
}
Utiliser les extensions StorageKey
StorageKey est un typedef pour String, et est accompagne d'un ensemble puissant de methodes d'extension :
// Save
await StorageKeysConfig.coins.save(100);
// Save with Backpack
await StorageKeysConfig.coins.save(100, inBackpack: true);
// Read
int? coins = await StorageKeysConfig.coins.read<int>();
// Read with default value
int? coins = await StorageKeysConfig.coins.fromStorage<int>(defaultValue: 0);
// Save/Read JSON
await StorageKeysConfig.coins.saveJson({"gold": 50, "silver": 200});
Map? data = await StorageKeysConfig.coins.readJson<Map>();
// Delete
await StorageKeysConfig.coins.deleteFromStorage();
// Delete (alias)
await StorageKeysConfig.coins.flush();
// Read from Backpack (synchronous)
int? coins = StorageKeysConfig.coins.fromBackpack<int>();
// Collection operations
await StorageKeysConfig.coins.addToCollection<int>(100);
List<int> allCoins = await StorageKeysConfig.coins.readCollection<int>();
Enregistrer/Lire du JSON
Stockez et recuperez des donnees JSON :
// Save JSON
Map<String, dynamic> user = {
"name": "Anthony",
"email": "anthony@example.com",
"preferences": {"theme": "dark"}
};
await NyStorage.saveJson("user_data", user);
// Read JSON
Map<String, dynamic>? userData = await NyStorage.readJson("user_data");
print(userData?['name']); // "Anthony"
TTL (Duree de vie)
Nylo Website v7 prend en charge le stockage de valeurs avec expiration automatique :
// Save with 1 hour expiration
await NyStorage.saveWithExpiry(
'session_token',
'abc123',
ttl: Duration(hours: 1),
);
// Read (returns null if expired)
String? token = await NyStorage.readWithExpiry<String>('session_token');
// Check remaining time
Duration? remaining = await NyStorage.getTimeToLive('session_token');
if (remaining != null) {
print('Expires in ${remaining.inMinutes} minutes');
}
// Clean up all expired keys
int removed = await NyStorage.removeExpired();
print('Removed $removed expired keys');
Operations par lots
Gerez efficacement plusieurs operations de stockage :
// Save multiple values
await NyStorage.saveAll({
'username': 'Anthony',
'score': 1500,
'level': 10,
});
// Read multiple values
Map<String, dynamic?> values = await NyStorage.readMultiple<dynamic>([
'username',
'score',
'level',
]);
// Delete multiple keys
await NyStorage.deleteMultiple(['temp_1', 'temp_2', 'temp_3']);
Introduction aux collections
Les collections vous permettent de stocker des listes d'elements sous une seule cle :
// Add items to a collection
await NyStorage.addToCollection("favorites", item: "Product A");
await NyStorage.addToCollection("favorites", item: "Product B");
// Read the collection
List<String> favorites = await NyStorage.readCollection<String>("favorites");
// ["Product A", "Product B"]
Ajouter a une collection
// Add item (allows duplicates by default)
await NyStorage.addToCollection("cart_ids", item: 123);
// Prevent duplicates
await NyStorage.addToCollection(
"cart_ids",
item: 123,
allowDuplicates: false,
);
// Save entire collection at once
await NyStorage.saveCollection<int>("cart_ids", [1, 2, 3, 4, 5]);
Lire une collection
// Read collection with type
List<int> cartIds = await NyStorage.readCollection<int>("cart_ids");
// Check if collection is empty
bool isEmpty = await NyStorage.isCollectionEmpty("cart_ids");
Mettre a jour une collection
// Update item by index
await NyStorage.updateCollectionByIndex<int>(
0, // index
(item) => item + 10, // transform function
key: "scores",
);
// Update items matching a condition
await NyStorage.updateCollectionWhere<Map<String, dynamic>>(
(item) => item['id'] == 5, // where condition
key: "products",
update: (item) {
item['quantity'] = item['quantity'] + 1;
return item;
},
);
Supprimer d'une collection
// Delete by index
await NyStorage.deleteFromCollection<String>(0, key: "favorites");
// Delete by value
await NyStorage.deleteValueFromCollection<int>(
"cart_ids",
value: 123,
);
// Delete items matching a condition
await NyStorage.deleteFromCollectionWhere<Map<String, dynamic>>(
(item) => item['expired'] == true,
key: "coupons",
);
// Delete entire collection
await NyStorage.delete("favorites");
Stockage Backpack
Backpack est une classe de stockage en memoire legere pour un acces synchrone rapide pendant la session d'un utilisateur. Les donnees ne sont pas persistees lorsque l'application se ferme.
Enregistrer dans Backpack
// Using helper
backpackSave('user_token', 'abc123');
backpackSave('user', userObject);
// Using Backpack directly
Backpack.instance.save('settings', {'darkMode': true});
Lire depuis Backpack
// Using helper
String? token = backpackRead('user_token');
User? user = backpackRead<User>('user');
// Using Backpack directly
var settings = Backpack.instance.read('settings');
Supprimer de Backpack
backpackDelete('user_token');
// Delete all
backpackDeleteAll();
Exemple pratique
// After login, store token in both persistent and session storage
Future<void> handleLogin(String token) async {
// Persist for app restarts
await NyStorage.save('auth_token', token);
// Also store in Backpack for quick access
backpackSave('auth_token', token);
}
// In API service, access synchronously
class ApiService extends NyApiService {
Future<User?> getProfile() async {
return await network<User>(
request: (request) => request.get("/profile"),
bearerToken: backpackRead('auth_token'), // No await needed
);
}
}
Persister avec Backpack
Stockez a la fois dans le stockage persistant et Backpack en un seul appel :
// Save to both
await NyStorage.save('user_token', 'abc123', inBackpack: true);
// Now accessible via Backpack (sync) and NyStorage (async)
String? tokenSync = Backpack.instance.read('user_token');
String? tokenAsync = await NyStorage.read('user_token');
Synchroniser le stockage avec Backpack
Chargez tout le stockage persistant dans Backpack au demarrage de l'application :
// In your app provider
await NyStorage.syncToBackpack();
// With overwrite option
await NyStorage.syncToBackpack(overwrite: true);
Sessions
Les sessions fournissent un stockage en memoire nomme pour regrouper des donnees liees (non persistees) :
// Create/access a session and add data
session('checkout')
.add('items', ['Product A', 'Product B'])
.add('total', 99.99)
.add('coupon', 'SAVE10');
// Or initialize with data
session('checkout', {
'items': ['Product A', 'Product B'],
'total': 99.99,
});
// Read session data
List<String>? items = session('checkout').get<List<String>>('items');
double? total = session('checkout').get<double>('total');
// Get all session data
Map<String, dynamic>? checkoutData = session('checkout').data();
// Delete a single value
session('checkout').delete('coupon');
// Clear entire session
session('checkout').clear();
// or
session('checkout').flush();
Persister les sessions
Les sessions peuvent etre synchronisees avec le stockage persistant :
// Save session to storage
await session('checkout').syncToStorage();
// Restore session from storage
await session('checkout').syncFromStorage();
Cas d'utilisation des sessions
Les sessions sont ideales pour :
- Les formulaires multi-etapes (integration, paiement)
- Les preferences utilisateur temporaires
- Les flux d'assistant/parcours
- Les donnees du panier d'achat
Enregistrer un modele
La classe de base Model fournit des methodes de stockage integrees. Lorsque vous definissez une key dans le constructeur, le modele peut s'enregistrer lui-meme :
class User extends Model {
String? name;
String? email;
// Define a storage key
static StorageKey key = 'user';
User() : super(key: key);
User.fromJson(dynamic data) : super(key: key) {
name = data['name'];
email = data['email'];
}
@override
Map<String, dynamic> toJson() => {
"name": name,
"email": email,
};
}
Enregistrer un modele
User user = User();
user.name = "Anthony";
user.email = "anthony@example.com";
// Save to persistent storage
await user.save();
// Save to both storage and Backpack
await user.save(inBackpack: true);
Relire un modele
User? user = await NyStorage.read<User>(User.key);
Synchroniser avec Backpack
Chargez un modele depuis le stockage dans Backpack pour un acces synchrone :
bool found = await User().syncToBackpack();
if (found) {
User? user = Backpack.instance.read<User>(User.key);
}
Collections de modeles
Enregistrez des modeles dans une collection :
User userAnthony = User();
userAnthony.name = 'Anthony';
await userAnthony.saveToCollection();
User userKyle = User();
userKyle.name = 'Kyle';
await userKyle.saveToCollection();
// Read back
List<User> users = await NyStorage.readCollection<User>(User.key);
Reference des extensions StorageKey
StorageKey est un typedef pour String. L'extension NyStorageKeyExt fournit ces methodes :
| Methode | Retour | Description |
|---|---|---|
save(value, {inBackpack}) |
Future |
Enregistrer une valeur dans le stockage |
saveJson(value, {inBackpack}) |
Future |
Enregistrer une valeur JSON dans le stockage |
read<T>({defaultValue}) |
Future<T?> |
Lire une valeur depuis le stockage |
readJson<T>({defaultValue}) |
Future<T?> |
Lire une valeur JSON depuis le stockage |
fromStorage<T>({defaultValue}) |
Future<T?> |
Alias pour read |
fromBackpack<T>({defaultValue}) |
T? |
Lire depuis Backpack (synchrone) |
toModel<T>() |
T |
Convertir une chaine JSON en modele |
addToCollection<T>(value, {allowDuplicates}) |
Future |
Ajouter un element a une collection |
readCollection<T>() |
Future<List<T>> |
Lire une collection |
deleteFromStorage({andFromBackpack}) |
Future |
Supprimer du stockage |
flush({andFromBackpack}) |
Future |
Alias pour deleteFromStorage |
defaultValue<T>(value) |
Future Function(bool)? |
Definir une valeur par defaut si la cle est vide (utilise dans syncedOnBoot) |
Exceptions de stockage
Nylo Website v7 fournit des exceptions de stockage typees :
| Exception | Description |
|---|---|
StorageException |
Exception de base avec message et cle optionnelle |
StorageSerializationException |
Echec de la serialisation de l'objet pour le stockage |
StorageDeserializationException |
Echec de la deserialisation des donnees stockees |
StorageKeyNotFoundException |
Cle de stockage introuvable |
StorageTimeoutException |
Delai d'attente depasse pour l'operation de stockage |
try {
await NyStorage.read<User>('user');
} on StorageDeserializationException catch (e) {
print('Failed to load user: ${e.message}');
print('Expected type: ${e.expectedType}');
}
Migration de l'ancien format
Nylo Website v7 utilise un nouveau format de stockage par enveloppe. Si vous effectuez une mise a niveau depuis la v6, vous pouvez migrer les anciennes donnees :
// Call during app initialization
int migrated = await NyStorage.migrateToEnvelopeFormat();
print('Migrated $migrated keys to new format');
Cela convertit l'ancien format (cles _runtime_type separees) vers le nouveau format par enveloppe. La migration peut etre executee plusieurs fois en toute securite — les cles deja migrees sont ignorees.