Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create Singleton class of SharedPreferences in flutter

Always required object of SharedPreferences but we access using await Like.

await SharedPreferences.getInstance();

That's why I thought create Singleton class of SharedPreferences and create static method for GET & SET data in SharedPreferences.

But I dont know how to do this, I try but cant get success
Please Help me

like image 251
Sanjayrajsinh Avatar asked Oct 15 '19 07:10

Sanjayrajsinh


People also ask

Is SharedPreferences a singleton?

I've noticed that a lot of projects have their SharedPreferences code scattered all over the project. The reason for this mostly is that fetching SharedPreference and reading/writing preferences as and when needed is the easiest thing to do when writing an app.

What is singleton class in flutter?

The singleton pattern is a pattern used in object-oriented programming which ensures that a class has only one instance and also provides a global point of access to it. Sometimes it's important for a class to have exactly one instance, or you might force your app into a weird state.

How do you save model class in SharedPreferences in flutter?

SharedPreferences: Save and Read First, in order to use the SharedPreferences , we have to use Flutter's plugin for it. To do so, make sure dependencies in your pubspec. yaml file looks similar to this: To save something in SharedPreferences , we must provide a value that we want to save and a key that identifies it.


3 Answers

For handle singleton class SharedPreference follow there 3 steps -

1. Put this class in your project

    import 'dart:async' show Future;
    import 'package:shared_preferences/shared_preferences.dart';

    class PreferenceUtils {
      static Future<SharedPreferences> get _instance async => _prefsInstance ??= await SharedPreferences.getInstance();
      static SharedPreferences _prefsInstance;

      // call this method from iniState() function of mainApp().
      static Future<SharedPreferences> init() async {
        _prefsInstance = await _instance;
        return _prefsInstance;
      }

      static String getString(String key, [String defValue]) {
        return _prefsInstance.getString(key) ?? defValue ?? "";
      }

      static Future<bool> setString(String key, String value) async {
        var prefs = await _instance;
        return prefs?.setString(key, value) ?? Future.value(false);
      }
    }


2. Initialize this class from your initState() of main class

PreferenceUtils.init();

3. Access your methods like

PreferenceUtils.setString(AppConstants.USER_NAME, "");
String username = PreferenceUtils.getString(AppConstants.USER_NAME);
like image 107
Sanjayrajsinh Avatar answered Nov 04 '22 00:11

Sanjayrajsinh


You can use following very simple class to get the SharedPreferences instance without await:

import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefs {
  static late final SharedPreferences instance;

  static Future<SharedPreferences> init() async =>
      instance = await SharedPreferences.getInstance();
}
  1. Initiliaze the instance maybe in main() function, as follows:
void main() async {
  // Required for async calls in `main`
  WidgetsFlutterBinding.ensureInitialized();

  // Initialize SharedPrefs instance.
  await SharedPrefs.init();

  runApp(MyApp());
}
  1. Access methods on SharedPrefs.instance, for e.g.:
final someString = SharedPrefs.instance.getString('someString') ?? 'defaultValue';
await SharedPrefs.instance.setBool('someBool', true);

Extra:
If preferred, one can further abstract by redefining these methods (getBool, setString, etc.) or defining new methods (getUser, setUser, setAccessToken etc.) in SharedPrefs class itself and making instance a private field like _instance.

One such example is as follows:

// Getter
static bool? getBool(String key) => _instance.getBool(key);

// Setter
static Future<bool> setBool(String key, bool value) => _instance.setBool(key, value);

// More abstraction
static const _kAccessToken = 'accessToken';

static Future<bool> setAccessToken(String value) => _instance.setString(_kAccessToken, value);

static String? getAccessToken() => _instance.getString(_kAccessToken);

After this, one can simply call these methods, as follows:

final someBool = SharedPrefs.getBool('someBool') ?? false;
await SharedPrefs.setBool('someBool', someBool);

final accessToken = SharedPrefs.getAccessToken();
like image 42
rmalviya Avatar answered Nov 04 '22 00:11

rmalviya


Here is my solution for prefs:

class Storage {
  static const String _some_field = 'some_field';

  static Future<SharedPreferences> get prefs => SharedPreferences.getInstance();

  static Future<String> getSomeStringData() async =>
      (await prefs).getString(_some_field) ?? '';

  static Future setSomeStringData(String phone) async =>
      (await prefs).setString(_some_field, phone);

  static Future clear() async {
    await getSomeStringData(null);
  }
}
like image 22
Andrey Turkovsky Avatar answered Nov 04 '22 00:11

Andrey Turkovsky