0

I have tried the answers in here How do you build a Singleton in Dart?

but I can't achieve what I want. so basically I want to make a Shared Preference Service as a singleton class. currently my code is like this. this is just a regular class, not a singleton.

class SharedPreferenceService {
  late SharedPreferences _prefs;

  SharedPreferenceService() {
    SharedPreferences.getInstance().then((value) => _prefs = value);
  }

  Future<void> setIntroPagesHaveBeenViewed() async {
    await _prefs.setBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
  }

  Future<bool> checkIfIntroPagesHaveBeenViewed() async {
    return _prefs.getBool(SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
  }
}

I need a singleton class, but when the instance is initialize for the first time, I also need to initialize _pref , so then I can access that _pref on the methods

Alexa289
  • 8,089
  • 10
  • 74
  • 178

1 Answers1

1

Your problem is that initialization is asynchronous. That means that the first time the singleton instance is accessed, that access needs to be asynchronous too (and so does any further access which happens before the initialization completes). However, the usage pattern of a singleton like this is such that you don't know which access is the first. So you have to make every access asynchronous.

Example:

class SharedPreferenceService {
  static final Future<SharedPreferences> _prefs = SharedPreferences.getInstance();

  Future<void> setIntroPagesHaveBeenViewed() async {
    await (await _prefs).setBool(
        SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
  }

  Future<bool> checkIfIntroPagesHaveBeenViewed() async {
    return (await _prefs).getBool(
        SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
  }
}

If all the methods are asynchronous anyway, that extra delay is not going to be a problem.

If you really, really only want to do that extra await if absolutely necessary, you can cache the value, like you try to here:

class SharedPreferenceService {
  static final Future<SharedPreferences> _prefsFuture = SharedPreferences.getInstance();
  static SharedPreferences? _prefs;

  Future<void> setIntroPagesHaveBeenViewed() async {
    var prefs = _prefs ??= await _prefsFuture;
    await _prefs.setBool(
        SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED, true);
  }

  Future<bool> checkIfIntroPagesHaveBeenViewed() async {
    var prefs = _prefs ??= await _prefsFuture;
    return _prefs.getBool(
        SharedPreferenceKey.INTRODUCTION_PAGES_HAVE_BEEN_VIEWED) ?? false;
  }
}
lrn
  • 64,680
  • 7
  • 105
  • 121