【Dart/Flutter】SharedPreferences等のString値に任意のMapを格納(取得)

2 min read読了の目安(約2600字

アプリ内データ保存「shared_preferences」を利用する際に、Mapを保存/取得をしたかった際の簡単な理解メモとなります。(もっと、便利になっているかもしれませんが。)

【Dart/Flutter】任意のMap⇔String

はじめに

  • 今回は、Map<DateTime, dynamic>を最終的にStringに変換(また、その逆)を考える

    • DateTimeクラス以外を利用する場合は、適宜変更
  • 実行環境

    • DartPadやAndroid Studio等で実行
      • Flutter 2.0.4 Dart SDK 2.12.2

エンコード

  • 変換の流れ
    • Map<DateTime, dynamic>Map<String, dynamic>
      • toString()関数により、keyをStringに変更
    • Map<String, dynamic>String
      • json.encode()関数は、import 'dart:convert';により利用
import 'dart:convert';

void main() {
  Map<DateTime, List<dynamic>> _events = {
    DateTime.now(): ['Test', 'List']
  };

  // エンコード汎用関数(Map<DateTime, dynamic>→Map<String, dynamic>)
  Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
    Map<String, dynamic> newMap = {};
    map.forEach((key, value) {
      newMap[key.toString()] = map[key];
    });
    return newMap;
  }

  // json.encodeでMapをStringへ
  String testEncoded = json.encode(encodeMap(_events));

  print(testEncoded.runtimeType);
  print(testEncoded);
}

実行結果

String
{"2021-04-07 18:09:24.454":["Test","List"]}

デコード

※エンコードしたtestEncoded値を今回は入力として利用

  • 変換の流れ
    • StringMap<String, dynamic>
      • json.decode()関数は、import 'dart:convert';により利用
    • Map<String, dynamic>Map<DateTime, dynamic>
      • DateTime.parse()関数により、keyをDateTimeに変更
import 'dart:convert';

void main() {
  Map<DateTime, List<dynamic>> _events = {
    DateTime.now(): ['Test', 'List']
  };

  // エンコード汎用関数(Map<DateTime, dynamic>→Map<String, dynamic>)
  Map<String, dynamic> encodeMap(Map<DateTime, dynamic> map) {
    Map<String, dynamic> newMap = {};
    map.forEach((key, value) {
      newMap[key.toString()] = map[key];
    });
    return newMap;
  }

  // json.encodeでMapをStringへ
  String testEncoded = json.encode(encodeMap(_events));

  // デコード汎用関数(Map<String, dynamic>→Map<DateTime, dynamic>)
  Map<DateTime, dynamic> decodeMap(Map<String, dynamic> map) {
    Map<DateTime, dynamic> newMap = {};
    map.forEach((key, value) {
      newMap[DateTime.parse(key)] = map[key];
    });
    return newMap;
  }

  Map<DateTime, List<dynamic>> newEvents = {};
  // json.decodeでStringをMapへ
  newEvents = Map<DateTime, List<dynamic>>.from(
    // 以下は、実際にはsharedPreferences等を利用し、取得したString値を入れる
    decodeMap(
      json.decode(testEncoded),
    ),
  );

  print(newEvents.runtimeType);
  print(newEvents);
}

実行結果

JsLinkedHashMap<DateTime, List<dynamic>>
{2021-04-07 18:31:18.014: [Test, List]}

※Dart Pad上での結果