Flutter storing Shared Preferences in a field

I use the same approach as the original poster suggests i.e. I have a global variable (actually a static field in a class that I use for all such variables) which I initialise to the shared preferences something like this:

in globals.dart:

class App {      
  static SharedPreferences localStorage;
  static Future init() async {
    localStorage = await SharedPreferences.getInstance();
  }
}

in main.dart:

void main() {
  start();
}

Async.Future start() async {
  await App.init();
  localStorage.set('userName','Bob');
  print('User name is: ${localStorage.get('userName)'}');  //prints 'Bob'
}

The above worked fine but I found that if I tried to use App.localStorage from another dart file e.g. settings.dart it would not work because App.localStorage was null but I could not understand how it had become null.

Turns out the problem was that the import statement in settings.dart was import 'package:<packagename>/src/globals.dart'; when it should have been import 'globals.dart;.


@iBob101 's answer is good, but still, you have to wait before you use the SharedPreferences for the first time.

The whole point is NOT to await for your SharedPreferences and be sure that it will always be NOT NULL.

Since you'll have to wait anyway let's do it in the main() method:

class App {      
  static SharedPreferences localStorage;
  static Future init() async {
    localStorage = await SharedPreferences.getInstance();
  }
}

And the main method:

void main() async{
  await SharedPref.initSharedPref();
  runApp(MyApp());
}

the line await SharedPref.initSharedPref(); takes ~100ms to execute. This is the only drawback as far as I can see.

But you definitely know that in every place in the app your sharedPreferenes instance in NOT NULL and ready for accessing it:

String s = App.localStorage.getString(PREF_MY_STRING_VALUE);

I think it's worthwhile


The cleanest way is to retrieve SharedPreferences in main method and pass it to MyApp as a dependency:

void main() async {
  // Takes ~50ms to get in iOS Simulator.
  final SharedPreferences sharedPreferences =
      await SharedPreferences.getInstance();

  runApp(MyApp(sharedPreferences: sharedPreferences));
}

class MyApp extends StatefulWidget {
  final SharedPreferences sharedPreferences;

  const MyApp({Key key, this.sharedPreferences})
      : assert(sharedPreferences != null),
        super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    // You can access shared preferences via widget.sharedPreferences
    return ...
  }

Tags:

Flutter