Getting Started With Shared Preferences in Flutter
If you want to store a small amount of persistent data that users can use later when they launch a mobile, using Shared Preferences is one of the ways to do it.
Shared Preferences provides a way of reading and storing such data in a key-value pair.
A common use-case of using Shared Preferences is when you want to store a JSON Web Token(JWT) on the app to authenticate users.
Flutter has a package that helps you store key-value pair data on disk called shared_preferences.
Installing the package
Add shared_preferences to your pubspec.yaml file
dependencies: shared_preferences: ^0.5.4+8
Using the package
The typical usage of shared_preferences will be as the code below.
var preferences = await SharedPreferences.getInstance();// Save a value
preferences.setString('value_key', 'hello preferences');// Retrieve value later
var savedValue = preferences.getString('value_key');
Instead, we will create a Shared Preferences Service so we can reduce a lot of boilerplate code and to make our code more readable.
Next, we will create a Utils folder in our flutter projects. In this Utils folder, create a new file called storage_util.dart.
Ideally, you may want to call the file name shared_preferences_util.dart. We will implement the shared_preferences flutter package as below.
import 'package:shared_preferences/shared_preferences.dart';
class StorageUtil {
static StorageUtil _storageUtil;
static SharedPreferences _preferences;
static Future<StorageUtil> getInstance() async {
if (_storageUtil == null) {
// keep local instance till it is fully initialized.
var secureStorage = StorageUtil._();
await secureStorage._init();
_storageUtil = secureStorage;
}
return _storageUtil;
}
StorageUtil._();
Future _init() async {
_preferences = await SharedPreferences.getInstance();
}
// get string
static String getString(String key, {String defValue = ''}) {
if (_preferences == null) return defValue;
return _preferences.getString(key) ?? defValue;
}
// put string
static Future<bool> putString(String key, String value) {
if (_preferences == null) return null;
return _preferences.setString(key, value);
}
}
What the storage_util file above does is to Read and Write key-value pair data using the getString and putString methods respectively.
Now, let’s use this service to save and retrieve data. We will build a simple UI like the one below. When you click on Save String, it will save a string in Shared Preferences.
Also, when the Get String button is clicked, it will get the value of the saved string from Shared Preferences.
The code to create the UI is below
import 'package:flutter/material.dart';
import 'package:shared_preference_project/utils/storageUtil.dart';
class Home extends StatefulWidget {
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
var savedString = '';
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Shared Preferences'),
),
body: Container(
padding: EdgeInsets.all(20).add(EdgeInsets.only(top: 20)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
RaisedButton(
onPressed: (){
StorageUtil.putString("myString", "My stored string in shared preferences");
},
textColor: Colors.white,
color: Colors.red,
padding: const EdgeInsets.all(8.0),
child: new Text(
"Save String",
),
),
Text(savedString, style: TextStyle(color: Colors.black),),
SizedBox(height: 60,),
RaisedButton(
onPressed: (){
setState(() {
savedString = StorageUtil.getString("myString");
});
},
textColor: Colors.white,
color: Colors.red,
padding: const EdgeInsets.all(8.0),
child: new Text(
"Get String",
),
),
],
),
),
);
}
}
We have declared a variable called savedString to hold the value of the saved string we are going to save in memory.
In the body of our Scaffold, we have two RaisedButtons. On the onPressed method of the Save String RaisedButton, we are calling
StorageUtil.putString("myString", "My stored string in shared preferences");
The first argument of the putString method holds the key in which case, we call it “myString” while the second argument holds the value of that key. We will need to remember this key to retrieve the data.
To retrieve the data, we call on the onPressed method of the Get String RaisedButton.
StorageUtil.getString("myString") // Get value of String
Conclusion:
To easily store a little chunk of data such as deviceIds, API tokens, user profiles, e.t.c you should make use of Shared Preferences.
While it is tempting to use it as it is in the docs, it is important for code readability that you should create a Shared Preferences Service as we have done in this article.
You can also extend the service class to include more methods like Clear, Save Int, Save Booleans, and others. You can find the source code for the sample app in this article in its GitHub Repository