0% found this document useful (0 votes)
61 views43 pages

05-Module 5

Uploaded by

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

05-Module 5

Uploaded by

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

CSE431

Mobile Programming

MODULE 5:
Data Persistence and Design Patterns
Module 5

1. Store key-value data on disk (Shared Preference)

2. Read and write files

3. Persist data with SQLite

4. Firebase – Real-Time-Database

5. Design Patterns

2
Store key-value data on disk
(Shared Preference)

3
Data Persistence
Store key-value data on disk (Shared Preference)

▪ 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 each platform. Fortunately, the
shared_preferences plugin can be used to persist key-value data
to disk on each platform Flutter supports.

▪ This recipe uses the following steps:

▪ Add the dependency.


▪ Save data.
▪ Read data.
▪ Remove data.

https://docs.flutter.dev/cookbook/persistence/key-value
4
Data Persistence
Store key-value data on disk (Shared Preference)

// Function to save value to SharedPreferences


void _saveValue() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.setString(_key, _value);
}

// Function to load saved value from SharedPreferences


void _loadSavedValue() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_value = prefs.getString(_key) ?? ""; // Using ?? "" to handle null case
});
}

https://docs.flutter.dev/cookbook/persistence/key-value
5
Read and write files

6
Data Persistence
Read and write files

• In some cases, you need to read and write files to disk. For
example, you might need to persist data across app launches, or
download data from the internet and save it for later offline use.

• To save files to disk on mobile or desktop apps, combine the


path_provider plugin with the dart:io library.

• This recipe uses the following steps:

• Find the correct local path.


• Create a reference to the file location.
• Write data to the file.
• Read data from the file.

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
7
Data Persistence
Read and write files - Find the correct local path

The path_provider package provides a platform-agnostic way to access


commonly used locations on the device's file system. The plugin currently
supports access to two file system locations:

Temporary directory
A temporary directory (cache) that the system can clear at any time. On iOS,
this corresponds to the NSCachesDirectory. On Android, this is the value that
getCacheDir() returns.

Documents directory
A directory for the app to store files that only it can access. The system clears
the directory only when the app is deleted. On iOS, this corresponds to the
NSDocumentDirectory. On Android, this is the AppData directory.

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
8
Data Persistence
Read and write files - Find the correct local path

This example stores information in the documents directory. You can find the
path to the documents directory as follows:

import 'package:path_provider/path_provider.dart';
// ···
Future<String> get _localPath async {
final directory = await getApplicationDocumentsDirectory();

return directory.path;
}

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
9
Data Persistence
Read and write files - Create a reference to the file location

Once you know where to store the file, create a reference to the file's full
location. You can use the File class from the dart:io library to achieve this.

Future<File> get _localFile async {


final path = await _localPath;
return File('$path/counter.txt');
}

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
10
Data Persistence
Read and write files - Write data to the file

Now that you have a File to work with, use it to read and write data. First,
write some data to the file. The counter is an integer, but is written to the file
as a string using the '$counter' syntax.

Future<File> writeCounter(int counter) async {


final file = await _localFile;

// Write the file


return file.writeAsString('$counter');
}

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
11
Data Persistence
Read and write files - Read data from the file

Now that you have some data on disk, you can read it. Once again, use the File
class.
Future<int> readCounter() async {
try {
final file = await _localFile;

// Read the file


final contents = await file.readAsString();

return int.parse(contents);
} catch (e) {
// If encountering an error, return 0
return 0;
}
}

https://docs.flutter.dev/cookbook/persistence/reading-writing-files
12
Persist data with SQLite

13
Data Persistence
Persist data with SQLite

• Flutter apps can make use of the SQLite databases via the
sqflite plugin available on pub.dev.

• Steps:
• 1. Add the dependencies
• 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.

14
Data Persistence
Persist data with SQLite

• To add the packages as a dependency, run flutter pub add:


flutter pub add sqflite path

Make sure to import the packages in the file you'll be working in.

import 'dart:async';

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

15
Data Persistence
Persist data with SQLite

2. Define the data model

Before creating the table to store information on the model, take a


few moments to define the data that needs to be stored.

For this example, define a Dog class that contains three pieces of
data: A unique id, the name, and the age of each dog.

class Dog {
final int id;
final String name;
final int age;

const Dog({
required this.id,
required this.name,
required this.age,
});
} 16
Data Persistence
Persist data with SQLite

3. Open the database

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.

// Avoid errors caused by flutter upgrade.


// Importing 'package:flutter/widgets.dart' is required.
WidgetsFlutterBinding.ensureInitialized();
// Open the database and store the reference.
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'),
);
17
Data Persistence
Persist data with SQLite

4. Create the dogs table

Next, create a table to store information about various Dogs. For this
example, create a table called dogs that defines the data that can be
stored. Each Dog contains an id, name, and age. Therefore, these are
represented as three columns in the dogs table.

1. The id is a Dart int, and is stored as an INTEGER SQLite Datatype. It


is also good practice to use an id as the primary key for the table
to improve query and update times.

2. The name is a Dart String, and is stored as a TEXT SQLite Datatype.

3. The age is also a Dart int, and is stored as an INTEGER Datatype.

18
Data Persistence
Persist data with SQLite

5. Insert a Dog into the database

Now that you have a database with a table suitable for storing
information about various dogs, it's time to read and write data.

First, insert a Dog into the dogs table. This involves two steps:

Convert the Dog into a Map


Use the insert() method to store the Map in the dogs table.

19
Data Persistence
Persist data with SQLite

6. Retrieve the list of Dogs

Now that a Dog is stored


in the database, query the
database for a specific dog
or a list of all dogs. This
involves two steps:

Run a query against the


dogs table. This returns a
List<Map>.
Convert the List<Map>
into a List<Dog>.

https://docs.flutter.dev/cookbook/persistence/sqlite
20
Data Persistence
Persist data with SQLite

In Flutter, when using SQLite to manage a database, handling duplicate entries


typically involves defining the database schema and the logic for inserting data.
Here's how it generally works:

Database Schema: You can enforce uniqueness on certain fields by creating


a unique index or adding a unique constraint to a column when you define
your table.

For example:

CREATE TABLE users ( id INTEGER PRIMARY KEY, username TEXT


UNIQUE, email TEXT UNIQUE);

In this case, both the username and email columns must be unique.

https://docs.flutter.dev/cookbook/persistence/sqlite
21
Data Persistence
Persist data with SQLite

In Flutter, when using SQLite to manage a database, handling duplicate entries


typically involves defining the database schema and the logic for inserting data.
Here's how it generally works:

Inserting Data:

When you attempt to insert a new record, SQLite checks for existing
records that violate the unique constraint. If a duplicate is found, SQLite will
raise an error.

You can handle this in Flutter using a try-catch block. For example:
try { await database.insert('users', userData, conflictAlgorithm:
ConflictAlgorithm.fail);}
catch (e) { // Handle the error (e.g., show a message to the user)
print('Duplicate entry: $e');}

https://docs.flutter.dev/cookbook/persistence/sqlite
22
Data Persistence
Persist data with SQLite

In Flutter, when using SQLite to manage a database, handling duplicate entries


typically involves defining the database schema and the logic for inserting data.
Here's how it generally works:

Conflict Resolution:

SQLite provides several options for how to handle conflicts when inserting
data.

The conflictAlgorithm parameter can be set to various strategies:

• ConflictAlgorithm.abort: Abort the operation and raise an error.


• ConflictAlgorithm.replace: Replace the existing row with the new one.
• ConflictAlgorithm.ignore: Ignore the new row if a conflict occurs.
• ConflictAlgorithm.update: Update the existing row with the new data.
For example, if you want to update existing records on conflict, you could
do:
https://docs.flutter.dev/cookbook/persistence/sqlite
codeawait database.insert('users', userData, conflictAlgorithm:
ConflictAlgorithm.replace)
23
Firebase – Real-Time-
Database

24
Data Persistence
Firebase – Real-Time-Database

https://firebase.google.com/docs/database/flutter/start

25
Design Patterns

26
Design Patterns
Flutter

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

27
Design Patterns
Flutter

MVC: Model-View-Controller

MVC is one of the most well-known design patterns in software


engineering. It separates the app into three interconnected
components:

•Model: The data layer of your application.

•View: The UI layer that displays the data.

•Controller: The logic that manages the communication between the


Model and the View.

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

28
Design Patterns
Flutter

Implementing MVC in Flutter

In Flutter, Widgets can act as Views, displaying the UI,


while the Controller can be a State object that manages the
Widget's state.

The Model would be separate Dart classes representing the


app's data.

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

29
Design Patterns
Flutter

Implementing MVC in Flutter

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

30
Design Patterns
Flutter Implementing MVC in Flutter

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

31
Design Patterns
Flutter

Implementing MVC in Flutter

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

32
Design Patterns
Flutter

MVP: Model-View-Presenter

MVP refines MVC by introducing a Presenter, which takes over the


business logic from the Controller.

Model: Similar to MVC, it represents the data.


View: Now, it's a passive interface that displays data and routes user
commands to the Presenter.

Presenter: Acts as the middle-man, retrieving data from the Model and
formatting it for the View.

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

33
Design Patterns
Flutter

MVP: Model-
View-Presenter

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

34
Design Patterns
Flutter
MVVM is a pattern that's particularly well-
suited for frameworks with rich data-binding
mechanisms, like Flutter.

MVVM: Model- Model: As before, it's the data layer.


View: The UI layer that binds to observable
View- variables in the ViewModel.
ViewModel
ViewModel: Exposes streams of data relevant
to the View and interprets user commands.

Flutter's Take on MVVM

Flutter's reactive framework makes it a good


candidate for MVVM, where StreamBuilder or
ValueNotifier can be used to reactively update
the UI.

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

35
Design Patterns
Flutter MVVM: Model-View-ViewModel: To-do-list app

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

36
Design Patterns
Flutter

MVVM: Model-View-
ViewModel: To-do-list
app

https://medium.com/@sparkleo/design-patterns-in-flutter-implementing-mvc-mvp-and-mvvm-2b2ff24ec077

37
Design Patterns
Flutter

Clean Architecture

https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1
38
Design Patterns
Flutter
Clean Architecture provides a way to structure applications
that separate the different components of an application
into modules, each with a well-defined purpose. The main
Clean Architecture idea behind Clean Architecture is to separate the application
into three main layers: the presentation layer,
the domain layer, and the data layer.

The View layer in MVVM


represents the Presentation
layer in Flutter Clean
Architecture, ViewModel
represents the Domain layer,
and the Model layer represents
the Data layer.

https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1
39
Design Patterns
Clean
Flutter
Architecture
1- Presentation Layer
Responsibility
The Presentation Layer is the outermost layer, responsible for presenting
information to the user and capturing user interactions. It includes all the
components related to the user interface (UI), such as widgets, screens, and
presenters/controllers (State Management).

Components
• Screens: Represent the feature screens.
• Widgets and UI Components: Represent the visual elements of the application.
• Manager/Controllers: Contain the presentation logic that interacts with the UI
components. They receive user input, communicate with the Use Cases in the
Domain Layer, and update the UI accordingly.
• The Manager/Controllers layer can incorporate any state management solution,
such as BloC, Riverpod, Provider, and others.

https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1
40
Design Patterns
Clean
Flutter
Architecture
2- Domain Layer

Responsibility
The Domain Layer, also known as the Business Logic or Use Case Layer, contains the
core business rules and logic of the application. It represents the heart of the
software system, encapsulating the essential functionality that is independent of
any particular framework.

Components
•Entities: Represent the fundamental business objects or concepts.
•Use Cases: Contain application-specific business rules and orchestrate the flow of
data between entities. They are responsible for executing specific actions or
operations.
•Business Rules and Logic (Repository): Core functionality that is crucial to the
application’s domain.

https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1
41
Design Patterns
Clean
Flutter
Architecture
3- Data Layer

Responsibility
The Data Layer is responsible for interacting with external data sources, such as
databases, network services, or repositories. It handles the storage and retrieval of
data.

Components
•Repositories or Gateways: Abstract interfaces that define how data is accessed and
stored.
•Data Models: Represent the structure of the data as it is stored in the external data
sources.
•Data Sources: Implementations of repositories that interact with databases, APIs,
or other external services.

https://medium.com/@yamen.abd98/clean-architecture-in-flutter-mvvm-bloc-dio-79b1615530e1
42
End of Module 5

You might also like