Storing persistent data is always something that a lot of developers have to think about. We want to keep track of where we’ve been, what we’ve seen, etc. Persistent means that the data will be remembered even if we close the application, so when we return to it, the data is still there.
There are several ways to store data. And normally we’d have to write something native, however, there are plugins available that we can use which help us.
One of these is the shared_preferences
plugin. Now this has some limitations including it is only good for primitive data (int
, double
, bool
, string
, and stringList
), and is not super fast. However, for small and simple data, this method can work well.
This library uses what’s known as a key-value pair. There is a key, and you can think of it like a variable name, and it is paired to some data, the value. This is the same concept of a map in dart.
How shared_preferences works
When you call shared preferences, as seen below, you are creating an object which you can then use. This is tied to your app, and allows you to both read and write data.
// obtain shared preferences
final prefs = await SharedPreferences.getInstance();
Saving Data
If you save data, you will need to use one of the setter methods available for the primitive types, such as setInt
, setBool
, and setString
.
These methods do two things simultaneously. First they update the data that is currently in memory, then they set the data on disk storage so that it can be accessed after the app is closed and restarted.
To save data, you would do something like the following:
// store a value
prefs.setInt('counter', counter);
prefs.setBool('flagged', true);
The variable counter is stored in the SharedPrefferences counter key to be used later. Notice that you can pass a variable, or a literal value into the methods.
Retrieving Data
You also of course need to retrieve data. There are getter methods which will allow you to do this.
// Try reading data from the counter key. If it doesn't exist, return 0.
final counter = prefs.getInt('counter') ?? 0;
Notice that you need to know what the key name and datatype are when retrieving the data.
But what if there is no data stored there for some reason (it got deleted, this is the first time it’s run on this machine, etc). Well that’s what the ?? is for.
The ??
is an if null. So if the getInt() (in this case) returns null, then use this other value.
Removing Data
Of course, you may need to remove data. That’s fairly simple luckily with the remove
method.
prefs.remove('counter');
Creating the Project
Of course, we’re going to have to create a sample project first, which I called simple_persistent_data
.
If you remember the initial project it is a counter, and then you click on the floating action button to increment, we’re going to expand upon that so it will remember what number we were at, so we can restart.
Adding the Dependency
The first thing we’re going to have to do is add the dependency. We’ve added dependency for Animations and dependencies for Network communication, so it shouldn’t be an issue.
Once again, we are going to open the pubspec.yaml
file and go to the dependencies. We’re going to add shared_preferences
, like you see below.
dependencies:
flutter:
sdk: flutter
shared_preferences: 2.0.7
I’m using version 2.0.7 even though there is a version 2.0.8 because the latest version requires a minor upgrade in dart to work. always check your logs/terminal window when you save to make sure it imports the necessary library.
Putting it together in the Sample App
After creating the sample app and removing the unnecessary comments, it’s time to put the shared_preferences
to work.
First, we need to import the shared_preferences library.
import 'package:shared_preferences/shared_preferences.dart';
In the _MyHomePageState class, we need to override the initState so it can call _LoadCounter.
@override
void initState() {
super.initState();
_loadCounter();
}
_LoadCounter is used to load the counter object when we start the app. It will utilize the read method.
void _loadCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = (prefs.getInt('counter') ?? 0);
});
}
The _incrementCounter will need to be updated so that it will not only add one to the increment state, but it will also store the value. Notice we do this with each change in case the app exits unexpectedly (crashes) we still have the value we need.
void _incrementCounter() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
_counter = (prefs.getInt('counter') ?? 0) + 1;
prefs.setInt('counter', _counter);
});
}
Notice that we are getting the current counter value through getInt() and then updating it, to make sure it is properly loaded.
That is all that is needed in order to get it up and running.
You can test in your browser or emulator and it should run. Now, one potential downside to testing is if you do a full reload the data is lost, it only works for hot reloads, but that is no big deal.
Storing Simple Data with Flutter was originally found on Access 2 Learn