AIエンジニアが一ヶ月でアプリ開発16:実装⑥(model作り)
こんにちは、りぼっちです。
さっそくですが掲題通り model の実装です。
model実装するわけ
以前 Firestore の実装はしたのですが、それだけだと常に同期する必要があるのと、やっぱりローカルでもデータを残しておきたいと思い、 shared_preferences を使おうと思うのですが、これだと JS のローカルストレージとかと一緒で文字列しか保存することができません。つまり構造体を保存するには構造体を JSONに変換して文字列として保存。保存された文字列を JSON にエンコードして、構造体に変換という流れが必要になります。
そのためにタスクやプロジェクトなど専用の構造体を作る必要があります。
普通モデルを作るときには、コンストラクタを使ってインスタンスを作成するいわゆるファクトリパターンが使われますが、Dart には専用の属性が用意されています。
Factory コンストラクタ
なんとなくネットの情報を見ていると Factoryパターン = singlton パターンだと思っている記事が多い気がするが、別にシングルトンである必要が無いのであれば、インスタンスを作れば良いと思う。
class Task() {
final String id;
Task({this.id});
factory Task(String id) {
return Task(id: id);
}
}
シングルトンの場合は以下のようになる
class Task() {
static Task _instance;
final String id;
Task({this.id});
factory Task(String id) {
if (_instance == null) {
_instance = Task(id: id);
}
return _instance;
}
}
ここに json からインスタンスを生成できるようにする。また逆変換のときは、 インスタンス -> Map -> Json string みたいに変換する必要になるため全体の model の感じは以下のようになる。
class Task() {
final String id;
Task({this.id});
factory Task.fromJSON(Map<String, dynamic> jsonData) {
return Task(id: jsonData["id"]);
}
static Map<String, dynamic> toMap(Task task) => {
"id": task.id
};
static String encodeTask(Task task) =>
json.encode(Task.toMap(task));
static Map<String, dynamic> decodeTask(String taskString) =>
Task.fromJSON(json.decode(taskString));
}
これで完成!
あとは shared_preferences の使い方は公式サイトを見ればわかるので、以下のように保存する。
# 保存
_prefs.setString("task", Task.encodeTask(task));
# 読み込み
Task task = Task.decodeTask(_prefs.getString("task"));
はい!超簡単ですね。
最後に
こんな感じで様々な値をローカルで保存できるようになったが、実際どれくらい溜まっているかとか、データをパージするライフサイクルとか定期的なDBとの整合性の担保とか、考え始めたら大変なのだが。
実際、アプリを落とさないまま、しばらく他のアプリを使ってて戻ってくるときに発火する仕組みとかってあるのだろうか?こういうときにアプリの開発経験が無いと厳しいな。
もう少し、アプリのライフサイクルイベントについて勉強する必要がありそう。っとはいえ、ローカルとクラウドの情報がズレないようにさえしておけば、あとはバックアップ程度に思っとけば良いはず!
なので次くらいには、そろそろ LP に取り掛かろうと思います。(たぶん)