Flutterでアプリ開発をする際にかなりの確率で使うことになるshared_preferencesをいい感じに使う方法を見つけたので備忘録として書いておく
こちらが公式ページ
インストール用のコマンド
flutter pub add shared_preferences
keyの管理をenumを使って行う
enum Pref {
sample,
}
shared_preferencesを利用するためにインスタンスを宣言する
何度も取得する必要はないので起動時にでもinitializeSharedPreferencesを読んであげればいいかと思います
late SharedPreferences _prefs;
Future<void> initializeSharedPreferences() async {
_prefs = await SharedPreferences.getInstance();
}
shared_preferencesには検索、削除、設定、取得の4パターンがあるので、これをextensionを利用して関数化する
1つ問題なのがshared_preferencesは型ごとに関数が分けられている
そのせいで共通化できないのでGenericsを利用することで型ごとに振り分ける
extension PrefExtension on Pref {
bool get contains => _prefs.containsKey(name);
Future<bool> get remove => _prefs.remove(name);
Future<bool> set<T>(T value) {
if (T == String) {
return _prefs.setString(name, value as String);
} else if (T == int) {
return _prefs.setInt(name, value as int);
} else if (T == double) {
return _prefs.setDouble(name, value as double);
} else if (T == bool) {
return _prefs.setBool(name, value as bool);
}
return Future.value(false);
}
T? get<T>() {
if (T == String) {
return _prefs.getString(name) as T?;
} else if (T == int) {
return _prefs.getInt(name) as T?;
} else if (T == double) {
return _prefs.getDouble(name) as T?;
} else if (T == bool) {
return _prefs.getBool(name) as T?;
}
return null;
}
}
利用する場合は下記のように呼んであげます
またgetの時にそれぞれ型を宣言する必要があるのでそれだけ忘れずに行ってください
// 検索
Pref.sample.contains
// 削除
await Pref.sample.remove
// 設定
await Pref.sample.set('テスト')
// 取得
Pref.sample.get<String>()
テスト内容はこんな感じです
test('string preferences test', () async {
SharedPreferences.setMockInitialValues({});
await initializeSharedPreferences();
// 空チェック
expect(Pref.sample.contains, false);
expect(Pref.sample.get<String>(), null);
// 値セット
expect(await Pref.sample.set('テスト'), true);
expect(Pref.sample.contains, true);
expect(Pref.sample.get<String>(), 'テスト');
// 値削除
expect(await Pref.sample.remove, true);
// 空チェック
expect(Pref.sample.contains, false);
expect(Pref.sample.get<String>(), null);
});
現在のshared_preferencesではStringのListしか対応していないので下記のようになります
もしintのListを保存したいのであればStingに変換して保存してあげればいいかと思います
独自クラスの場合はMapにしてからString側のjsonにする感じですね
Future<bool> setList<T>(List<T> value) {
if (T == String) {
return _prefs.setStringList(name, value as List<String>);
}
return Future.value(false);
}
List<T>? getList<T>() {
if (T == String) {
return _prefs.getStringList(name) as List<T>?;
}
return null;
}
類似