--- title: Flutter. Desant dades en local tags: DAW, Flutter --- <div style="width: 30%; margin-left: auto;"> ![](https://hackmd.io/_uploads/HJiR4eGJT.png) </div> <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Llicència de Creative Commons" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />Aquesta obra està subjecta a una llicència de <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Reconeixement-CompartirIgual 4.0 Internacional de Creative Commons</a> ![images](https://hackmd.io/_uploads/S1KDuPXrp.jpg) # Desant dades en local. Per a desar dades de manera local, en principi, hauriem d'escriure codi nadiu per a cada plataforma i integrar-lo a la nostra aplicació en Flutter. Per sort, existeix el plugin [shared_preferences](https://pub.dev/packages/shared_preferences). Tot i que les dades desades amb shared preferences, en teoria són persitents en disc de manera asíncrona, ningú ens garanteix la seva persistència, raò per la qual, no l'hem de fer servir per desar dades crítiques. Els tipus de dades admesos com a valor són: * int * double * bool * String * List<String> En cas de necessitar desar estructures més complexes, sempre podem utilitzar el valor String per serialitzar objectes. Per a poder utilitzar shared_preferences al nostre codi, hem d'afegir-lo al fitxer pubspec.yaml com a dependència. ```bash= $ flutter pub add shared_preferences ``` ## Exemples d'ús Escriure dades ```= // Obtain shared preferences. final SharedPreferences prefs = await SharedPreferences.getInstance(); // Save an integer value to 'counter' key. await prefs.setInt('counter', 10); // Save an boolean value to 'repeat' key. await prefs.setBool('repeat', true); // Save an double value to 'decimal' key. await prefs.setDouble('decimal', 1.5); // Save an String value to 'action' key. await prefs.setString('action', 'Start'); // Save an list of strings to 'items' key. await prefs.setStringList('items', <String>['Earth', 'Moon', 'Sun']); ``` Llegir dades ```python= // Try reading data from the 'counter' key. If it doesn't exist, returns null. final int? counter = prefs.getInt('counter'); // Try reading data from the 'repeat' key. If it doesn't exist, returns null. final bool? repeat = prefs.getBool('repeat'); // Try reading data from the 'decimal' key. If it doesn't exist, returns null. final double? decimal = prefs.getDouble('decimal'); // Try reading data from the 'action' key. If it doesn't exist, returns null. final String? action = prefs.getString('action'); // Try reading data from the 'items' key. If it doesn't exist, returns null. final List<String>? items = prefs.getStringList('items'); ``` Esborrar dades ```python= // Remove data for the 'counter' key. await prefs.remove('counter'); ``` ## Testing En codi de testing, podem reemplaçar la implementació de la nostra instància de SharedPreferences amb una implementació mock amb valors inicials. D'aquesta forma, obtindrem una implementació '_a memoria_' que no desarà cap dada a disc. ```python= final Map<String, Object> values = <String, Object>{'counter': 1}; SharedPreferences.setMockInitialValues(values); ``` ## Exemple complert ```= import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() => runApp(const MyApp()); class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( title: 'Shared preferences demo', home: MyHomePage(title: 'Shared preferences demo'), ); } } class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); final String title; @override State<MyHomePage> createState() => _MyHomePageState(); } class _MyHomePageState extends State<MyHomePage> { int _counter = 0; @override void initState() { super.initState(); _loadCounter(); } // Load the initial counter value from persistent storage on start, // or fallback to 0 if it doesn't exist. Future<void> _loadCounter() async { final prefs = await SharedPreferences.getInstance(); setState(() { _counter = prefs.getInt('counter') ?? 0; }); } /// After a click, increment the counter state and /// asynchronously save it to persistent storage. Future<void> _incrementCounter() async { final prefs = await SharedPreferences.getInstance(); setState(() { _counter = (prefs.getInt('counter') ?? 0) + 1; prefs.setInt('counter', _counter); }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(widget.title), ), body: Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( 'You have pushed the button this many times: ', ), Text( '$_counter', style: Theme.of(context).textTheme.headlineMedium, ), ], ), ), floatingActionButton: FloatingActionButton( onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), ), ); } } ``` ## Localització de les dades segons plataforma. | Plataforma | Localitzacio | |---|---| | Android | SharedPreferences | | iOS | NSUserDefaults | | Linux | In the XDG_DATA_HOME directory| | macOS | NSUserDefaults | | Web | LocalStorage | | Windows | In the roaming AppData directory |