0% found this document useful (0 votes)
6 views42 pages

Lecture 8 _ Data Persistence and serialization

The lecture covers data persistence and serialization in Flutter, focusing on using Shared Preferences, JSON files, and local databases. It explains how to store key-value data, read and write JSON files, and utilize SQLite databases for larger data sets. Additionally, it discusses serialization strategies, including manual and automated approaches for encoding and decoding data.

Uploaded by

qaed.qw2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views42 pages

Lecture 8 _ Data Persistence and serialization

The lecture covers data persistence and serialization in Flutter, focusing on using Shared Preferences, JSON files, and local databases. It explains how to store key-value data, read and write JSON files, and utilize SQLite databases for larger data sets. Additionally, it discusses serialization strategies, including manual and automated approaches for encoding and decoding data.

Uploaded by

qaed.qw2
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 42

Lecture 8 : Data Persistence

and serialization

T.Fatima Al-azazi
Agenda

● Using Shared Preferences


● Working with files in Flutter app,
● JSON files
● Serialization
● Using Local Database

2
Storing Key-Value data

3
Store key-value data on disk

● If you have a relatively small collection of key-values to save,


you can use the shared_preferences plugin.
● Normally, you would have to write native platform
integrations for storing data on both iOS and Android.
Fortunately, the shared_preferences plugin can be used to
persist key-value data on disk. The shared preferences plugin
wraps NSUserDefaults on iOS and SharedPreferences on
Android, providing a persistent store for simple data.

4
Using Shared_preferences

1. Add the dependency


Before starting, add the shared_preferences package as a
dependency.
To add the shared_preferences package as a dependency, run
flutter pub add:

5
Save Data
● To persist data, use the setter methods provided by the
SharedPreferences class.
● Setter methods are available for various primitive types, such
as setInt, setBool, and setString.
● Setter methods do two things: First, synchronously update the
key-value pair in-memory. Then, persist the data to disk.

// obtain shared preferences


final prefs = await SharedPreferences.getInstance();
// set value
await prefs.setInt('counter', counter);

6
Read data

● To read data, use the appropriate getter method provided by


the SharedPreferences class. For each setter there is a
corresponding getter. For example, you can use the getInt,
getBool, and getString methods.
//content_copy
final prefs = await SharedPreferences.getInstance();
// Try reading data from the counter key. If it doesn't exist,
return 0.
final counter = prefs.getInt('counter') ?? 0;

7
Remove data

To delete data, use the remove() method.


content_copy
final prefs = await SharedPreferences.getInstance();

await prefs.remove('counter');

8
Using Json Files

9
JSON

● JavaScript Object Notation (JSON) is a common open-


standard and language-independent file data format with the
benefit of being human-readable text.
● Persisting data is a two-step process;
○ first you use the File class to save and read data.
○ second, you parse the data from and to a JSON format.
● You’ll create a class to handle saving and reading the data
file that uses the File class.
● You’ll also create a class to parse the full list of data by using
json.encode and json.decode and a class to extract each
record.
10
UNDERSTANDING THE JSON FORMAT

● The JSON format is text-based and is independent of programming


languages, meaning any of them can use it.
● It’s a great way to exchange data between different programs
because it is human-readable text.
● JSON uses the key/value pair, and the key is enclosed in quotation
marks followed by a colon and then the value like "id":"100".
● You use a comma (,) to separate multiple key/value pairs.

11
Value Types in Json

● The types of values you can use are Object, Array, String,
Boolean, and Number.
● Objects are declared by curly ({}) brackets, and inside you
use the key/value pair and arrays.
● You declare arrays by using the square ([]) brackets, and
inside you use the key/value or just the value.

12
13
14
15
Example

● The JSON file is used to save and read the journal data from the
device local storage area, resulting in data persistence over app
launches.
● You have the opening and closing curly brackets declaring an
object.
● Inside the object, the journal’s key contains an array of objects
separated by a comma.
● Each object inside the array is a journal entry with key/value
pairs declaring the id, date, mood, and note.
● The id key value is used to uniquely identify each journal entry
and isn’t displayed in the UI.
● How the value is obtained depends on the project requirement;
16
Journal App’s Json file

17
USING CLASSES TO WRITE and READ JSON

● import the dart:io library to use the File class responsible


for saving and reading files.
● It also requires you to import the path_provider package
to retrieve the local path to the document directory.
● The class requires you to import the dart:convert library to
decode and encode JSON objects.

18
Retrieve the Directory Path

● The first task in local persistence is to retrieve the directory path where
the data file is located on the device.
● Local data is usually stored in the application documents directory; for iOS,
the folder is called NSDocumentDirectory, and for Android it’s AppData.
● To get access to these folders, you use the path_provider package (Flutter
plugin). You’ll be calling the getApplicationDocumentsDirectory()
method, which returns the directory giving you access to the path variable

19
Creating a File

● Once you retrieve the path, you append the data filename by
using the File class to create a File object.
● You import the dart:io library to use the File class, giving you
a reference to the file location.

20
Reading and Writing in Json
● Once you have the File object, you use the writeAsString()
method to save the file by passing the data as a String
argument.
● To read the file, you use the readAsString() method without
any arguments. Note that the file variable contains the
document

21
RETRIEVING DATA WITH THE FUTUREBUILDER

● A FutureBuilder widget works with a Future to retrieve the


latest data without blocking the UI.
● The three main properties that you set are initialData, future,
and builder.
● initialData: Initial data to show before the snapshot is
retrieved
● future: Calls a Future asynchronous method to retrieve
data.
● builder: The builder property provides the BuildContext and
AsyncSnapshot (data retrieved and connection state). The
AsyncSnapshot returns a snapshot of the data, and you can
also check for the ConnectionState to get a status on the
data retrieval process. 22
AsyncSnapshot in FutureBuilder
● AsyncSnapshot: Provides the most recent data and connection status.
● Note that the data represented is immutable and read-only.
● To check whether data is returned, you use the snapshot.hasData.
● To check the connection state, you use the snapshot.connectionState to
see whether the state is active, waiting, done, or none.
● You can also check for errors by using the snapshot.hasError property

23
FutureBuilder() sample code

24
Serialization

25
Encoding and Decoding

● The JSON file data is stored as plain text (strings).


● To save data to the JSON file, you use serialization to convert
an object to a string.
● To read data from the JSON file, you use deserialization to
convert a string to an object.
● You use the json .encode() method to serialize and the
json.decode() method to deserialize the data.
● Note that both the json.encode() and json.decode() methods
are part of the JsonCodec class from the dart:convert library.

26
jsonEncode and jsonDecode

● To serialize and deserialize JSON files, you import the dart:convert library.
● After calling the readAsString() method to read data from the stored file, you need
to parse the string and return the JSON object by using the json.decode() or
jsonDecode() function.
● Note that the jsonDecode() function is shorthand for json.decode().
● To convert values to a JSON string, you use the json.encode() or jsonEncode()
function. Note that jsonEncode() is shorthand for json.encode().
● It’s a personal preference deciding which approach to use; in the exercises, you’ll
be using json.decode() and json.encode().

27
Serialization

● Encoding and serialization are the same thing—turning a data


structure into a string.
● Decoding and deserialization are the opposite process—
turning a string into a data structure.
● However, serialization also commonly refers to the entire
process of translating data structures to and from a more
easily readable format.

28
Serialization Strategies

● two general strategies for working with JSON:


○ Manual serialization
○ Automated serialization using code generation
● Different projects come with different complexities and use
cases.
● For smaller proof-of-concept projects or quick prototypes,
using code generators might be overkill.
● For apps with several JSON models with more complexity,
encoding by hand can quickly become tedious, repetitive,
and lend itself to many small errors.
29
Manual serialization

● Manual JSON decoding refers to using the built-in JSON


decoder in dart:convert.
● It involves passing the raw JSON string to the jsonDecode()
function, and then looking up the values you need in the
resulting Map<String, dynamic>.
● It has no external dependencies or particular setup process,
and it’s good for a quick proof of concept.
● Manual decoding does not perform well when your project
becomes bigger. Writing decoding logic by hand can become
hard to manage and error-prone.

30
Automated serialization
● JSON serialization with code generation means having an
external library generate the encoding boilerplate for you.
● After some initial setup, you run a file watcher that
generates the code from your model classes.
● For example, json_serializable and built_value are these
kinds of libraries.
● This approach scales well for a larger project. No hand-
written boilerplate is needed.
● The downside with code generation is that it requires some
initial setup.
● Also, the generated source files might produce visual clutter
in your project navigator. 31
Using Local Database

32
Local Database

● If you are writing an app that needs to persist and query


large amounts of data on the local device, consider using a
database instead of a local file or key-value store.
● In general, databases provide faster inserts, updates, and
queries compared to other local persistence solutions.
● Flutter apps can make use of the SQLite databases via the
sqflite plugin available on pub.dev.

33
Sqfllite package

● To work with SQLite databases, import the sqflite and path


packages.
● The sqflite package provides classes and functions to
interact with a SQLite database.
● The path package provides functions to define the location
for storing the database on disk.
● To add the packages as a dependency, run flutter pub add
● Make sure to import the packages in the file you’ll be
working in.

34
Open the database

● Before creating the table to store information, take a few moments to


define the data that needs to be stored.
● Before reading and writing data to the database, open a connection to
the database. This involves two steps:
1. Define the path to the database file using getDatabasesPath() from

the sqflite package, combined with the join function from the path
package.
2. Open the database with the openDatabase() function from sqflite.

35
final database = openDatabase(

// Set the path to the database. Note: Using the `join` function
from the

// `path` package is best practice to ensure the path is correctly

// constructed for each platform.

join(await getDatabasesPath(), 'doggie_database.db'),

);

36
Creating tables
create a table to store information

onCreate: (db, version) {

// Run the CREATE TABLE statement on the database.

return db.execute(

'CREATE TABLE dogs(id INTEGER PRIMARY KEY, name TEXT,


age INTEGER)',

);

},
37
Insert the Object into the database

1. Convert the Object into a 2. Use the insert() method to


Map store the Map in the table.
Map<String, dynamic> await db.insert(
toMap() {
'dogs',
return {
dog.toMap(),
'id': id,
conflictAlgorithm:
'name': name,
ConflictAlgorithm.replace,
'age': age,};}
);
38
Retrieve the list of Objects
2. Convert the List<Map> into
a List<Object>
query the database for a List.generate(maps.length, (i)
specific Object or a list of all {
Objects involves two steps
return Dog(
1. Run a query against the
id: maps[i]['id'],
table. This returns a
List<Map>. name: maps[i]['name'],

age: maps[i]['age'],
final List<Map<String,
dynamic>> maps = await );});
db.query('dogs');
39
Update a Dog in the database

you might want to update that


await db.update(
information at a later time. You
can do this by using the 'dogs',
update() method from the
dog.toMap(),
sqflite library.
where: 'id = ?',
This involves two steps:
whereArgs: [dog.id],
1. Convert the Dog into a
Map. );
2. Use a where clause to
ensure you update the
40
correct Dog.
Delete from the database

you can also remove from the database. To delete data, use the
delete() method
await db.delete(

'dogs',

// Use a `where` clause to delete a specific dog.

where: 'id = ?',

// Pass the Dog's id as a whereArg to prevent SQL injection.

whereArgs: [id],

); 41
Assignment 7

● Explain with example how to use FutureBuilder.


● Which permissions do you need to add while using local
storage?
● In your project Apply shared preference and persist data
ether with json file or local database .

42

You might also like