Flutter almacenamiento local

Esta sección presentará las soluciones de almacenamiento local en Flutter, incluyendo SharedPreferences, almacenamiento de archivos y base de datos SQLite.


SharedPreferences - almacenamiento ligero

SharedPreferences es adecuado para almacenar datos simples de pares clave-valor.

Agregar dependencia

dependencies:
  shared_preferences: ^2.0.0

Ejemplo: uso de SharedPreferences

import 'package:shared_preferences/shared_preferences.dart';

// Guardar datos
Future<void> saveData() async {
  final prefs = await SharedPreferences.getInstance();

  // Guardar cadena
  await prefs.setString('username', 'Zhang San');

  // Guardar entero
  await prefs.setInt('age', 25);

  // Guardar valor booleano
  await prefs.setBool('isLoggedIn', true);

  // Guardar lista (cadena JSON)
  await prefs.setStringList('tags', ['flutter', 'dart']);
}

// Leer datos
Future<void> loadData() async {
  final prefs = await SharedPreferences.getInstance();

  final username = prefs.getString('username') ?? '';
  final age = prefs.getInt('age') ?? 0;
  final isLoggedIn = prefs.getBool('isLoggedIn') ?? false;
  final tags = prefs.getStringList('tags') ?? [];

  print('Usuario: $username');
  print('Edad: $age');
  print('Conectado: $isLoggedIn');
  print('Etiquetas: $tags');
}

// Eliminar datos
Future<void> deleteData() async {
  final prefs = await SharedPreferences.getInstance();

  // Eliminar uno
  await prefs.remove('username');

  // Eliminar todos
  await prefs.clear();
}

Almacenamiento de archivos

Use path_provider para obtener el directorio de documentos de la aplicación y realizar el almacenamiento de archivos.

Agregar dependencia

dependencies:
  path_provider: ^2.0.0

Ejemplo: lectura y escritura de archivos

import 'dart:io';
import 'package:path_provider/path_provider.dart';

// Obtener el directorio de documentos
Future<Directory> get _documentDirectory async {
  return await getApplicationDocumentsDirectory();
}

// Escribir archivo
Future<void> writeFile() async {
  final dir = await _documentDirectory;
  final file = File('${dir.path}/my_file.txt');

  // Escribir texto
  await file.writeAsString('Hello Flutter!');

  // Escribir bytes
  final bytes = [72, 101, 108, 108, 111];  // "Hello"
  await file.writeAsBytes(bytes);
}

// Leer archivo
Future<void> readFile() async {
  final dir = await _documentDirectory;
  final file = File('${dir.path}/my_file.txt');

  if (await file.exists()) {
    // Leer texto
    final content = await file.readAsString();
    print('Contenido del archivo: $content');

    // Leer bytes
    final bytes = await file.readAsBytes();
    print('Bytes: $bytes');
  }
}

// Almacenamiento de archivos JSON
Future<void> saveJson() async {
  final dir = await _documentDirectory;
  final file = File('${dir.path}/data.json');

  final data = {
    'name': 'Zhang San',
    'age': 25,
    'skills': ['Flutter', 'Dart'],
  };

  // Guardar JSON con jsonEncode
  await file.writeAsString(jsonEncode(data));
}

Base de datos SQLite

Use sqflite para operaciones de base de datos SQLite.

Agregar dependencia

dependencies:
  sqflite: ^2.0.0
  path: ^1.8.0

Ejemplo: operaciones básicas de SQLite

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';

// Clase auxiliar de base de datos
class DatabaseHelper {
  static final DatabaseHelper instance = DatabaseHelper._init();
  static Database? _database;

  DatabaseHelper._init();

  Future<Database> get database async {
    if (_database != null) return _database!;
    _database = await _initDB('my_app.db');
    return _database!;
  }

  // Inicializar base de datos
  Future<Database> _initDB(String filePath) async {
    final dbPath = await getDatabasesPath();
    final path = join(dbPath, filePath);

    return await openDatabase(
      path,
      version: 1,
      onCreate: _createDB,
    );
  }

  // Crear tabla
  Future<void> _createDB(Database db, int version) async {
    await db.execute('''
      CREATE TABLE users(
        id INTEGER PRIMARY KEY AUTOINCREMENT,
        name TEXT NOT NULL,
        email TEXT NOT NULL,
        age INTEGER
      )
    '
'');
  }

  // Insertar datos
  Future<int> insertUser(Map<String, dynamic> user) async {
    final db = await database;
    return await db.insert('users', user);
  }

  // Consultar todos los usuarios
  Future<List<Map<String, dynamic>>> getAllUsers() async {
    final db = await database;
    return await db.query('users');
  }

  // Consulta condicional
  Future<List<Map<String, dynamic>>> getUserByName(String name) async {
    final db = await database;
    return await db.query(
      'users',
      where: 'name = ?',
      whereArgs: [name],
    );
  }

  // Actualizar datos
  Future<int> updateUser(int id, Map<String, dynamic> user) async {
    final db = await database;
    return await db.update(
      'users',
      user,
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  // Eliminar datos
  Future<int> deleteUser(int id) async {
    final db = await database;
    return await db.delete(
      'users',
      where: 'id = ?',
      whereArgs: [id],
    );
  }

  // Cerrar base de datos
  Future<void> close() async {
    final db = await database;
    db.close();
  }
}

// Ejemplo de uso
Future<void> dbExample() async {
  final db = DatabaseHelper.instance;

  // Agregar usuario
  await db.insertUser({
    'name': 'Zhang San',
    'email': '[email protected]',
    'age': 25,
  });

  // Consultar todos
  final users = await db.getAllUsers();
  print('Lista de usuarios: $users');

  // Actualizar usuario
  await db.updateUser(1, {'name': 'Li Si', 'age': 30});

  // Eliminar usuario
  await db.deleteUser(1);
}

Selección de solución de almacenamiento: para pares clave-valor simples use SharedPreferences, para estructuras complejas use SQLite, y el almacenamiento de archivos es adecuado para archivos grandes.

Otras extensiones