🔁
【Flutter】Shared_PreferencesでListを含んでいるインスタンスを保存
背景
アラームアプリを作成したのですが、List<〇〇>の変数を保存する必要がありました。
そういった変数をShared_Preferencesで保存する筆者のやり方をここで紹介します。
保存・取得の手順
複雑なデータ(ListやMap)を保存・取得するためには
データをShared_Preferencesで保存できる状態に変換する。
そして取得してきたデータをアプリで使える状態に再変換する。
といった処理が必要になります。下記が変換手順になります。
List<〇〇>を保存・取得する場合の変換手順
List<〇〇>
↓↑
List<Map<String, dynamic>> //Map型を格納した変換
↓↑
List<String> //Json形式の文字列を格納したListに変換
取り扱うクラス
freezedを使ってAlarmStyleクラスを定義しました。
この定義内でMap型への変換、Map型からの変換を行う関数も定義します。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'alarm_style.freezed.dart';
@freezed
class AlarmStyle with _$AlarmStyle {
const AlarmStyle._();
const factory AlarmStyle({
required bool state,//OnOff情報
required DateTime time,//時刻
required List<bool> routine00,//定期的な鳴動についての情報①
required List<bool> routine01,//定期的な鳴動についての情報②
required List<bool> routine02,//定期的な鳴動についての情報③
}) = _AlarmStyle;
// Map形式に変換
Map<String, dynamic> toJson() {
return {
'state': state,
'time': time.toIso8601String(),
'routine00': routine00,
'routine01': routine01,
'routine02': routine02,
};
}
// Map形式からの変換
factory AlarmStyle.fromJson(Map<String, dynamic> json) {
return AlarmStyle(
state: json['state'],
time: DateTime.parse(json['time']),
routine00: List<bool>.from(json['routine00']),
routine01: List<bool>.from(json['routine01']),
routine02: List<bool>.from(json['routine02']),
);
}
}
保存するコード
下記の1行のコードでAlarmStyleを1つずつMap型に変換し、Json形式に文字列型に変換した変数を
まとめてListにしている。
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:convert';
saveList(List<AlarmStyle> alarmList) async {
final prefs = await SharedPreferences.getInstance();
//この1行で保存のための変換を行なっている。
List<String> alarmStyleStrings =
alarmList.map((alarmStyle) => jsonEncode(alarmStyle.toJson())).toList();
await prefs.setStringList('alarm_list', alarmStyleStrings);
}
取得するコード
先ほどとは逆でreturnのコードでJson形式の文字列型変数を1つずつMap型に変換し、AlarmStyle型
まとめてListにしている。
Future<List<AlarmStyle>> loadList() async {
const String keyAlarmList = 'alarm_list';
final prefs = await SharedPreferences.getInstance();
final List<String>? encodedList = prefs.getStringList(keyAlarmList);
//何も保存されていない場合は7:00のアラームを生成
if (encodedList == null) {
return [
AlarmStyle(
state: false,
time: DateTime(2000, 1, 1, 7, 0, 0, 0, 0),
routine00: [true],
routine01: [false, false],
routine02: [false, false, false, false, false, false, false])
];
}
//この1行で取得のための変換を行なっている。
return encodedList
.map((encodedAlarm) => AlarmStyle.fromJson(jsonDecode(encodedAlarm)))
.toList();
}
Discussion