Flutterと個人開発
はじめに
筋トレの成果をビフォーアフターとして表現できるアプリ
「tsumugu(ツムグ)」をリリースしました🎉
ネイティブアプリ初挑戦でしたが、Flutter/Dartのキャッチアップ期間も含め、約2ヶ月半でリリースまで漕ぎ着けることができました!
本記事ではtsumuguの紹介と個人開発についてまとめようと思います(技術的な話は少なめです)
tsumuguの紹介
日々のトレーニングを記録して、あなただけのビフォーアフターを作成できます。
筋トレ(トレーニング)って、どうもやる気が出ない時ありますよね...
私の場合だと大体トレーニングしている時間帯はAM5:00-6:00。
とにかく眠いですし、
特にこれからの冬の時期は自分に負けがちです。
(夜明け、暗闇、孤独、1人、うち秘めた炎、をイメージしたトーンになってます)
そんな時でも、
日々の小さな積み重ねでしか、自分自身の秤だったり、基準を超えることはできないのだと自覚的になれるサービス。
筋トレ(トレーニング)を通じて、自分自身の物語や想いを紡いでいけるようなサービス。
そんなサービスが欲しくて「tsumugu(ツムグ)」を作りました。
↓ 「筋トレ ビフォーアフター」でググった結果...
こういったビフォーアフター画像を簡単に生成できて、SNSでシェアすることができます!
100点は無理でも40点のUI
個人開発っぽくないUI
tsumuguを作る上で、特に気を使いました。
40点ぐらいのUIにはなったのではないでしょうか?
アプリ開発はFlutterしか触ったことないですが、UIをサクサク作れるのは素晴らしい体験でした
ホーム | マイページ | ビフォーアフター |
---|---|---|
↓ 多いのか少ないのかわかりませんが、このぐらいの規模感です
github.com/AlDanial/cloc v 1.90 T=0.10 s (829.3 files/s, 89073.3 lines/s)
-------------------------------------------------------------------------------
Language files blank comment code
-------------------------------------------------------------------------------
Dart 86 988 252 7997
-------------------------------------------------------------------------------
SUM: 86 988 252 7997
-------------------------------------------------------------------------------
アーキテクチャについて
Flutter + Firebase(Firestore、Auth、Storage)
Riverpod(Flutter Hooks) + StateNotifier + freezed
こちらをベースに進めました。当初は、ChangeNotifierで進めていましたが、StateNotifierがいけてそうとか、色々な想いが出てきて、今はChangeNotifierとStateNotifierが同居してます...😓
アーキテクチャについては一緒に開発してくれた相方のhs7さんがまとめてくれましたので、ぜひご覧ください。
フォルダー構成について
現状は、レイヤーごとにディレクトリをMVVMで切ってますが、
viewModelが肥大化するのと、どのページ(関心)で利用されているのかパッと見わかり辛いといった理由から絶賛悩み中ではあります。
関心でまとめた方がわかりやすかったかな...と思い始めてます(特にこのぐらいの規模感なら尚更)
↓ こんな感じです
- before_after
- ui
- controller
- state
- model
- reppository
- profile
- ui
- controller
- state
- model
- reppository
- settings
ただ関心でまとめると、一画面で複数の関心を跨いだときにどうするか?など都度新しい関心が登場するたびに結構悩みそうな予感がしてます。
主な機能
ここではトレーニング記録の登録・編集とビフォーアフターについて取り上げてみようと思います。
(詳細は記載せず、利用したパッケージと何をしているかを記載してます)
トレーニング登録・編集 | ビフォーアフター |
---|---|
トレーニング記録
パッケージ名 | 用途 |
---|---|
file_picker | 画像アップロード |
photo_view | 画像ギャラリー |
reorderables | ドラッグ&ドロップ |
画像アップロードについて
登録ボタン押下時に、サムネイル生成 -> 実画像・サムネイルをStorageにアップロード -> FireStoreに保存してます。
当初は、CloudFunctionsを利用して、StorageへのuploadイベントにフックしてCloud Functionsを起動させサムネイル画像を生成してました。
しかし、下記の理由からクライアント側でサムネイル生成をする方針にしました。
(特に2は個人開発なので、可能な限り無料で使いたかったので致命的でした)
- サムネイル画像アップロード直後数秒はサムネイルの存在を保証できないため、取扱いにひと工夫必要。
- 複数画像をアップロードすると、CloudFunctionsでメモリ不足で、割り当てメモリ増やす必要がある。
今のところ、そこまで体験上そこまで気にならないので、このままでいきますが、
チューニング余地ありだなと思ってます。
ビフォーアフター
パッケージ名 | 用途 |
---|---|
image_cropper | 画像切り抜き |
screenshot | ビフォーアフターのスクショ |
share_plus | シェア |
ビフォーアフターの生成について
ビフォーとアフターの画像選択時に画像を切り抜くためにimage_cropper
を利用しています。
登録ボタン押下時にscreenshot
を利用して、選択したビフォーとアフターの画像をスクリーンショットとして取得します。このスクリーンショットが実際にシェアされる画像になります。
※share_plusを利用すると、Slackで画像がシェアされません...回避方法ご存知の方いれば🙇
Tips
作りながら学ぶ
相方はわかりませんが、
ぼくのFlutter経験は半年前ぐらいにチュートリアルをやった程度で、ネイティブアプリの経験もなかったのでほぼゼロスタートの状態でした。
体系的に学ばず、必要な箇所をネットでつまみ食いしながら進めました。
そのせいで初期に書いたコードはなかなかしんどい感じにはなってますが、結果的にかなりスピードが出たのではないかと思います。
おそらく、次何か新しい技術を学ぶときもこの方式を取ると思います。そのぐらい濃い数ヶ月を過ごすことができました!
短い期間で完走する
今回は同僚と作ったわけですが、二人とも本業があり、作業時間としては、平日2hと土日。
所感ですが、大体一緒に作ろう系の9割は途中で頓挫する印象ですが、今回は下記を意識することでなんとかリリースまで漕ぎ着けることができました!(僕も過去に一度頓挫したことがあります)
- 毎日1行だけでもcommitする!
- 頻度高く話す場を設ける
- 歩幅を合わせる
歩幅が合わないなら一人でやったほうが良いと実感しました。 - 微妙でも良いからレビュー依頼を出す
特に初期実装時は、可読性、パフォーマンス、エラーハンドリングは一旦TODOにしておき、とりあえず動くところまでできたらレビュー!を繰り返していきました。これが作りながら新しい技術を学び、スピードを出す上で一番ハマったことだなと思ってます。 - 時折コミット数とか比較して煽りあう
無理せず外注する
アプリのアイコンとアプリ内で利用する画像は外注しました。私には無理でした。
ココナラというサービスを利用しましたが、そこまで費用をかけずに満足のいくアウトプットを得ることができたのでおすすめです。
これから
スケジュールドリブンで進めたのでかなり機能を削ぎ落としました。
なので、これから少しずつアップデートをしていく所存です。
筋トレアプリの本丸である、履歴管理
も近々着手していきます!
※ 履歴管理とは、ベンチプレス100kgとか記録できることを指してます
最後に
一緒に開発してくれたhs7さんありがとうございます!
たぶん1人でFlutterを始めてたら、だらだらとまだサンプルアプリ(よくあるTODOアプリとか)を作っていたと思います。
Discussion