clicksrv
clicksrv

Reputation: 90

SharedPreferences.getInstance() is always returning null

Coming from Object Oriented Programming Background, I planned on making a dedicated Settings Class to store certain basic data about the app.

I planned on starting with saving the theme of the application using SharedPreferences and LocalStorage.

However, SharedPreferences.getInstance() always seems to be returning null.

I have tried simply running, running in Debug mode, having a separate async method to load the SharedPreferences and returning a Future which is unwrapped using .then(). I can't seem to figure out why I am always getting null from SharedPreferences.getInstance() in the AppSettings.getInstance() method that I have written.

import 'package:shared_preferences/shared_preferences.dart';
import 'package:localstorage/localstorage.dart';
import 'package:flutter/material.dart';

class AppSettings {
  // Singleton Instance
  static AppSettings _appSettings;

  // For First Launch Recognition
  bool _initialize;

  // Storage instances for persistent settings storage
  static SharedPreferences _prefs;
  static LocalStorage _dayColors = new LocalStorage('_dayColors');
  static LocalStorage _nightColors = new LocalStorage('_nightColors');

  // App Settings
  bool _nightTheme;

  Color _dayBgColor;
  Color _primaryDayColor;
  Color _secondaryDayColor;
  Color _accentDayColor;

  Color _nightBgColor;
  Color _primaryNightColor;
  Color _secondaryNightColor;
  Color _accentNightColor;

  static AppSettings getInstance() {
    SharedPreferences.getInstance().then((prefs) => _prefs = prefs);
    _appSettings ??= AppSettings._();
    return _appSettings;
  }

  ///
  /// Initialize App Settings
  ///
  AppSettings._() {
    _checkIfFirstLaunch();
    if (_initialize) {
      _loadDefaultSettings();
      _saveSettings();
    } else {
      _loadSettings();
    }
  }

  _checkIfFirstLaunch() {
    try {
      _initialize = _prefs.getBool("_initialize");
    } catch (e) {
      _initialize = true;
    }
  }

  _loadSettings() {
    _nightTheme = _prefs.getBool("_nightTheme");

    _dayColors.ready.then((_) => _loadDayColors());
    _nightColors.ready.then((_) => _loadNightColors());
  }

  _loadDefaultSettings() {
    _nightTheme = false;

    _dayBgColor = Colors.white;
    _primaryDayColor = Colors.blue;
    _secondaryDayColor = Colors.lightBlue;
    _accentDayColor = Colors.blueAccent;

    _nightBgColor = Colors.black54;
    _primaryNightColor = Colors.green;
    _secondaryNightColor = Colors.lightGreen;
    _accentNightColor = Colors.amber;
  }

  _saveSettings() {
    _prefs.setBool("_nightTheme", _nightTheme);

    _dayColors.ready.then((_) => _saveDayColors());
    _nightColors.ready.then((_) => _saveNightColors());
  }
}

SharedPreferences.getInstance() should return SharedPreferences singleton instance. It keeps returning null.

Upvotes: 0

Views: 1422

Answers (2)

clicksrv
clicksrv

Reputation: 90

Here is the code that worked based on Augusto's answer:

static Future<AppSettings> getInstance() async {
    _prefs = await SharedPreferences.getInstance();
    _appSettings ??= AppSettings._();
    return _appSettings;
}

Upvotes: 0

Augusto
Augusto

Reputation: 4233

Your function is async and your callback (then) executes after of the return of getInstance(). You must change your function to use await and get the value of SharedPreferences.getInstance() instead use SharedPreferences.getInstance().then(...)

Look the documentation: https://pub.dev/documentation/shared_preferences/latest/shared_preferences/SharedPreferences/getInstance.html

Implementation of SharedPreferences.getInstance().

static Future<SharedPreferences> getInstance() async {
  if (_instance == null) {
    final Map<String, Object> preferencesMap =
        await _getSharedPreferencesMap();
    _instance = SharedPreferences._(preferencesMap);
  }
  return _instance;
}

Upvotes: 3

Related Questions