AIエンジニアが一ヶ月でアプリ開発18:実装⑦(タイムスタンプ)
こんにちは、りぼっちです。
今日は実装を進めます。
前回の実装でモデルを作りましたが、モデルには CreatedAt と UpdatedAt のカラムが含まれていました。この部分を保存するときの実装をします。
Flutter の DateTime型
これは非常に扱いやすい時間の関数です。
DateTime _now = DateTime.now(); # 2020-09-15 21:23:39.928999
(DateFormat('yyyy/MM/dd HH:mm').format(_now); # 2020/09/15 21:23
こんな感じで扱える。これを UpdatedAt や CreatedAt に入れるのだが、この時間型を shared_preference や Firestore で、どうやって扱えば良いかを紹介する。
DateTime側を shared_preference で保存する
shared_preference は様々なものを保存できるが、構造体を保存するときには基本的に JSON のように Dart でいう Map<String, dynamic> 型を文字列型に変換して保存する。
DateTime型も文字列型にするわけだが、そのままではデコードする時が面倒なので、そもそも JSON にするときに文字列型にしてしまう。文字列にするのは以下の通り
String _nowString = _now.toString();
一方で、もとの DateTime型に戻すときは次のように行う
DateTime _now = DateTime.parse(_nowString);
これで簡単に時間型が扱える。
DateTime 型を Firestore に保存する
FireStore は、いくつかのタイプを保存することができるが、時間を保存するときには Timestamp型を使う。DateTime型をTimestamp 型で保存するためには、実は何もしなくて良い。
そのまま DateTime 型の Value を保存すれば自動で Timestamp型に変換してくれる。
問題は、逆のときだ。ドキュメントの Timestamp型は自動で Datestamp型に変換されないので以下のように変換してやる必要がある。
( data["createdAt"] as Timestamp ).toDate()
これで DateTime型として扱える。
文字列型かTimestamp型のどちらからでも変換できるようにする
モデルのように、Map型からクラスのインスタンスを作る場合、時間のカラムにどちらの型が入っていても DateTime型としてインスタンスを生成できることが望ましい。そこで以下のように対応すれば良い。
updatedAt = data["updatedAt") is Timestamp ? data["updatedAt"].toDate() : DateTime.parse(data["updatedAt"]);
三項演算子にしてしまえば、効率よく変換できるし、 is を使って型識別をしているので二項目で as を使って型指定してやる必要が無くなる。
最後に
今回は、Flutter での時間の扱い方について紹介した。
実装もかなり進んできて、あとは細かい調整や設定画面を作るのが残っている。ここが地味に時間がかかる。一ヶ月で開発するためには、いかに細かいところを早く作るか or 作り込まないか!だと思う。
性格上、どうしても完璧にしてからリリースしたいと思ってしまうが、それだとフィードバックなどがもらえず、モチベーションも上がらないので出来れば、ある程度動くようになったらリリースに向けて動きたいと思います。
次は、LPの続きをしたいところ。