How to create a single instance of shared preferences which can be used in full project in flutter
Asked Answered
A

5

11

Whenever we have to use shared preferences we have to create an instance of it.

In flutter creating an instance of shared preference is asynchronous;

final prefs = await SharedPreferences.getInstance();

we have to create its instance always whenever we have to use it like above.

Is there a way to create a single instance of shared preferences which will be available to the overall project and we don't have to create its instance again and again in Flutter?

Allegraallegretto answered 20/7, 2022 at 5:22 Comment(0)
S
10

To create Singleton class of SharedPreference:

Put this class in 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);
         }
       }
Initialize this class in initState() main class
 void main() async {
  // Required for async calls in `main`
  WidgetsFlutterBinding.ensureInitialized();

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

  runApp(MyApp());
}
Access in methods
PreferenceUtils.setString(AppConstants.USER_ID, "");
String userId = PreferenceUtils.getString(AppConstants.USER_ID);

more: https://dev.to/lucianojung/flutter-singelton-pattern-1a38

Schaffel answered 20/7, 2022 at 5:29 Comment(1)
if you're happy with the answer you should mark it correct and up vote it,,thanksSchaffel
N
2

SharedPreferences.getInstance() returns already a Singleton. It reads once from disk and subsequent calls just return the resolved future. This way, just store the object returned by the await SharedPreferences.getInstance(); somewhere accessible globally.

Check out its source code below. It creates the static _completer once for the lifetime of the app.

  /// Loads and parses the [SharedPreferences] for this app from disk.
  ///
  /// Because this is reading from disk, it shouldn't be awaited in
  /// performance-sensitive blocks.
  static Future<SharedPreferences> getInstance() async {
    if (_completer == null) {
      final Completer<SharedPreferences> completer = Completer<SharedPreferences>();
      try {
        final Map<String, Object> preferencesMap = await _getSharedPreferencesMap();
        completer.complete(SharedPreferences._(preferencesMap));
      } on Exception catch (e) {
        // If there's an error, explicitly return the future with an error.
        // then set the completer to null so we can retry.
        completer.completeError(e);
        final Future<SharedPreferences> sharedPrefsFuture = completer.future;
        _completer = null;
        return sharedPrefsFuture;
      }
      _completer = completer;
    }
    return _completer!.future;
  }
Newark answered 20/7, 2022 at 5:37 Comment(0)
M
0

Apart from creating a singleton separately you can also do this.. You can create a dart file with methods defined globally. By globally i mean outside the class.

late SharedPreferences prefs;
void initiateSharedPreferences()
{
   prefs = await SharedPreferences.getInstance();
}

From main.dart call this method to initiate prefs. Now the var pref is globally available. Now wherever you use prefs you only have to import this dart file and you can use prefs normally.

Martyry answered 20/7, 2022 at 5:47 Comment(0)
W
0

Use a simple Service Locator for Dart get_it. You will have many such cases when you have to have a global object to work with other than SharedPreferences too. The first step is to add dependencies for get_it. Just go to a link, and flollow steps below to set shared preferences below up.

Your SharedPreferences will be

import 'package:flutter/cupertino.dart';
import 'package:shared_preferences/shared_preferences.dart';

class SharedPrefs extends ChangeNotifier {
  SharedPreferences? _prefsInstance;

  SharedPrefs() {
    _init();
  }

  Future<void> _init() async {
    _prefsInstance = await SharedPreferences.getInstance();
    getIt.signalReady(this);
  }

  bool getBool(String key, [bool elseValue = false]) {
    return _prefsInstance?.getBool(key) ?? elseValue;
  }

  Future<bool> setBool(String key, bool value) async {
    return _prefsInstance?.setBool(key, value) ?? Future.value(false);
  }
}

In main.dart

import 'package:flutter/material.dart';
import 'package:get_it/get_it.dart';
import 'package:yourpackage/shared_prefs.dart';

import 'app.dart';

GetIt getIt = GetIt.instance;

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  getIt.registerSingleton(SharedPrefs(), signalsReady: true);
  runApp(const App());
}

Anywhere you need shared preferences you call it

final authenticated = getIt<SharedPrefs>().getBool('key_auth');
Written answered 20/7, 2022 at 8:39 Comment(0)
B
0
import 'package:shared_preferences/shared_preferences.dart';

class SharedPreference {
  static SharedPreferences? prefs;

  static String token = 'token';
  static String dataListKey = 'dataListKey';

  static Future<void> addData(Map<String, String> data) async {
     prefs = await SharedPreferences.getInstance();
     List<String> dataList = prefs?.getStringList(dataListKey) ?? [];
     dataList.add(jsonEncode(data));
     await prefs!.setStringList(dataListKey, dataList);
  }

  static Future<List<Map<String, String>>> getDataList() async {
     prefs = await SharedPreferences.getInstance();
     List<String> dataList = prefs?.getStringList(dataListKey) ?? [];
     return dataList
    .map((data) => Map<String, String>.from(jsonDecode(data)))
    .toList();
  }

  static Future<void> clearDataList() async {
     prefs = await SharedPreferences.getInstance();
     await prefs!.remove(dataListKey);
  }

  static addStringToSF(String key, String value) async {
    prefs = await SharedPreferences.getInstance();
    prefs!.setString(key, value);
  }

  static addIntToSF(String key, int value) async {
    prefs = await SharedPreferences.getInstance();
    prefs!.setInt(key, value);
  }

  static addBoolToSF(String key, bool value) async {
    prefs = await SharedPreferences.getInstance();
    prefs!.setBool(key, value);
  }

  static Future<String> getStringValuesSF(String key) async {
    prefs = await SharedPreferences.getInstance();
    String? getString = prefs!.getString(key);
    return (getString != null) ? getString : '';
  }

  static Future<int> getIntValuesSF(String key) async {
    prefs = await SharedPreferences.getInstance();
    int? getString = prefs!.getInt(key);
    return (getString != null) ? getString : 0;
  }

  static Future<bool> getBoolValuesSF(String key) async {
    prefs = await SharedPreferences.getInstance();
    bool? getbool = prefs!.getBool(key);
    return (getbool != null) ? getbool : false;
  }

  static Future<bool> removeValues(String key) async {
    prefs = await SharedPreferences.getInstance();
    return await prefs!.remove(key);
  }

  static dynamic containsKey(String key) async {
    prefs = await SharedPreferences.getInstance();
    return prefs!.get(key);
  }

  static Future<bool> removePrefs() async {
    prefs = await SharedPreferences.getInstance();
    return await prefs!.clear();
  }
}


  SharedPreference.addStringToSF(
            SharedPreference.token, logindata11.token.toString());

class Constant {
  static String token = '';
}

 Constant.token =
        await SharedPreference.getStringValuesSF(SharedPreference.token);
Brentonbrentt answered 22/2 at 7:5 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Pickerelweed

© 2022 - 2024 — McMap. All rights reserved.