🌎

Webフロントエンジニアが、FlutterでもSignalを使ってアプリ開発してみたら最高だった話

2024/08/21に公開
4

はじめに

こんにちは! よこ(@snakeshift3431)です😊
この度Flutterを使って人生初の個人開発アプリをリリースしたので、
技術解説兼ねてこの場で軽くご紹介させて頂けたらなと思います!

経歴

Webフロント歴7年。
サーバ実装の実務経験なし。
アプリ開発の実務経験なし。
デザインその他諸々もなし。

作ったもの

こんなのです。
https://until-moss-grows.web.app/

AppStoreへのリンクはこちらから
https://apps.apple.com/app/id6547858108

どういったアプリか

オンライン上でゆるーく繋がりながら集中記録を付けられるアプリです。

ユーザは「キャンプ」と呼ばれる目的を持ったコミュニティに参加(作成)でき、
同じ目的を持ったユーザ同士で目標や作業のリアルタイム感を共有することで、
モチベーションを維持しながらやってこうぜ、みたいなのを狙っています。

主なターゲットは受験生、資格、その他プログラミングなど日常的に勉強や活動している人たちです。

使用した技術 (特筆すべきものだけ)

Flutter

JSに慣れているならReact Nativeを使えば良かったのですが、
それだとWeb開発の延長になってしまい、せっかくならアプリエンジニアとしての自覚が持てそうなこちらを選びました。
あとは単純に第二言語を学びたかったと言うのもあります。

もしWeb技術にするなら、今なら割り切ってCapacitorを選択するかなと思います。
https://capacitorjs.jp/

◆ Signal(状態管理)

恐らく日本人初じゃないかなと思うのですが、状態管理としてSignalだけを使ってアプリを構築しています。
SignalベースのWebフレームワークを使っている人間として、正直これのおかげでめちゃくちゃ開発が楽になりました。
そこで得た知見や設計手法の共有が今回のテーマです!
https://dartsignals.dev/

◆ Bonfire(ゲームエンジン)

WebでいうPhaserやpixijsのようなゲームエンジンです。
光の表現を加えたいがために入れましたが、導入したことでスプライトアニメーションなど他の面でも色々楽できたかなと思います。ちなみにフォーク元のFlameエンジンでは光の表現は扱えません。
https://bonfire-engine.github.io/#/

◆ isar(ローカルDB)

残念ながら私はリレーショナルなDBを扱えないので、Firebaseと同じNoSQLタイプを探していたところ、こちらが見つかりました。集中時間の記録を端末内に保存するのに使用しています。
https://isar.dev/ja/

Firebase

私みたいな、サーバ知識よわよわなフロントエンジニアの味方です。
AWS AmplifyもGraphQLなどで少し経験ありましたが、手軽さやFlutterとの相性の良さでやはりこちら。
掲示板作るくらいの知識は元々あったので、今回ちゃんと学んだのはdartでの書き方とセキュリティルールくらいです。
https://firebase.google.com/?hl=ja

Revenuecat

アプリ内の定期購読機能で利用しました。
開発に入る前から、どう考えても課金周りはやべーなという認識を持っていたのですが、
これのおかげで1週間苦しむ程度で済みました。(appleの規則で購入情報の復元が必須なのですが、匿名認証使っていたのでその辺りの考慮がしんどかったです。)

https://www.revenuecat.com/

開発期間や方針決め

まず最初の2ヶ月間をDartやFlutterの学習期間に割り当てて、Udemyで受講したりZennの体系的に学べる本を買ってひたすらインプットしていました。
その後の4ヶ月間を企画からデザイン、開発までの期間としました。

企画段階からの流れとしては、


①自分が日常的に使うアプリを作りたい
→集中タイマー系のアプリに決定。

②最初にデザイン(画像)を考える
→世界観を決めたい。まず有料素材サイト(itch.ioUnityAssetStoreなど)を漁る。
→ピクセルアート調の動物がイケていたのでメインビジュアルはそれに決定。

③デザインに合わせてコンセプトを考える
→ユーザーを動物、コミュニティをキャンプということにして、一緒にオンライン上で集中できるアプリに何やかんや決定。
→この時点で実装に着手開始。

④コンセプトに合わせて機能を考える
→コンセプトを満たすために必要な機能を思いつく→実装するの繰り返し
→adobeみたいなデザインツールは使えないので、2ヶ月くらいはコードレベルでのデザインの検討と実装に使った。


といった感じで、
作りたいシステム、入れたい機能を考えてからデザインに落として、必要な画像を作って、、ではなく、
画像に合わせてそれに合うデザイン、コンセプトや機能のアイデアを考えて実装しました。

そもそも私の場合は画像を作るのが一番無理だったので、最初にそこをクリアしている必要がありました。作ってから欲しい画像がない、じゃシャレになりませんし妥協に繋がるためこのような流れになりました。

使用技術や背景の説明が済んだところで、ここからがSignalの説明です!

Signalとはなんぞや

リアクティブプログラミングの概念の一つであり、
データの変更を監視し、変更があった場合に自動的に反応(更新)する仕組みを提供するものです。

view側においては更新があった際にbuildメソッド全体を再評価するのではなく、
その状態に依存している要素だけを効率よく更新出来るので、
よく Fine-Grained Reactivity(きめ細かな反応性) なんかと呼ばれています。

Webフロント開発においては主にパフォーマンス面やそのシンプルで強力なAPIが評価され、
Reactを除く主要なフレームワークほぼ全て(Vue, Angular, Svelte, Solid, Qwik, Preactなど)で、
状態管理における結論 として近年デファクト採用されています。

Reactではエコシステムが巨大なこともあり状態管理は様々な分派があるのですが、
他のフレームワークにおいては「状態管理に何使う?」はそもそも話題になりません。Signal一択です。

また最近はJS標準でもSignalを取り入れる提案がされたことで少し話題になりました。
(Vue.jsの生みの親であるEvan氏も参加しています。)

https://twitter.com/mweststrate/status/1775967066937303174
https://twitter.com/youyuxi/status/1776560691572535341

もしpureJSでSignalが扱える、状態管理ができるようになったとしたら、
それはjQueryの役目がES6に取って換わったように、 何らかのパラダイムシフト を起こすことになるかもしれません。

Evan氏の言うように標準のSignalに迎合した形を取っておけば、
フレームワーク間での状態を含んだロジックの共有が容易になる可能性がありますし、
この流れを無視することは フレームワークやエコシステム全体にとっての利益に繋がらなくなるのではないか、と個人的には思っています👀

・・・はい、これだけ言っておけばSignalへの興味を持っていただけましたかね・・・?

なぜFlutter開発でSignalを採用するのか

私がFlutter開発を始めてみて気付いたのは、
Webの文化が少し時間をおいてからアプリ方面に流入してきているんだな と言う事実です。

Flutterで今一番メジャーな状態管理手法が、
flutter_hooks(+riverpod) であると言うのはほぼ間違いないと思っていますが、
ご存知の通り、これは元々Reactから流入してきたものです。

であるならばWebフロント開発においてSignalが主流となったら、
Flutterにも時間をおいてからその流れが来る可能性は十分あります。
(というかその流れを早めたくてこの記事を書いていたり)

何よりも、Signalはhooksほど覚えることも多くなく、扱う難易度も低いです。

widget内外の状態を管理するためにhooksとriverpodを両方覚えなくても良いです。
HookWidgetもHookConsumerWidgetも継承する必要はありません。

使うのはFlutter標準の StatelessWidgetStatefulWidget 、あといくつかのSignal APIだけです!

実装編に関しては長くなってしまったのでQiitaの方に分けました。
Vue3のCompositionAPIライクにFlutter開発をしてみる話

ここではSignal系のフロント開発で実績のある、Vue3のCompositionAPIをバイブルとして、
同じような設計手法でFlutter開発を行うための具体的なコードを書いています。
(注)開発時はSignalパッケージ5.3.0を使っていましたが、現在は5.4.0なので内容が一部異なっている可能性があります。

ご興味のある方がいましたら覗いてみてください😇

最後に

今回初めてのアプリ開発にFlutterを選んで、その状態管理にSignalを選んだことは、個人的には大正解だったと思います!

理由は、

  • 慣れ親しんだWeb開発の流れで実装ができたこと
  • 参考になる記事がなくてもAPI自体が既にミニマルで覚えることが少なかったこと
  • 無駄な再レンダリングを減らせてパフォーマンスが向上できたこと

そして何よりSignalはどの環境でも通用する知識であると言うことを再確認できたことです。
昨今はWebもアプリも宣言的UIがベースなので、状態の流れは画面の流れであり、アプリケーション全体の流れでもあります。

Signalというリアクティブプログラミングの一つの概念を、その開発の流れを一度覚えてしまえば、
それが別のフレームワークであったとしても、あるいは今回のように環境から違ったとしても、APIの動きは絶対に似通うので問題なく開発が行えます。

もしSignal系のWeb開発者でアプリ開発にチャレンジしてみたい方は、是非Flutter✖️Signalの採用をご検討してみてください
今回私がご紹介したcompositionAPIライクな設計手法は、Webでの開発体験にかなり近いものになりました。

逆にFlutterからSignalを知ってWebも挑戦してみたい方は、Reactだけじゃなく是非Signal系のフロントフレームワークも覗いてみてください
同じような流れで動いていることが実感できると思います。

Signalがもっともっと広く認知されて、使われていくことを祈って〆とします。ここまで読んで頂きありがとうございました!

Discussion

JboyHashimotoJboyHashimoto

アプリの紹介ページのアニメーションみて感動しました笑
Flutter Webなんですね。意外。。。。

アプリインストールしてみました!
UIが、iOSのようなデザインしてる。UI綺麗ですね。素敵なアプリです。

よこよこ

jboyさん

ありがとうございます!!
ランディングページは一から作るよりも、
そのままWeb用にビルドすれば楽なのでは?とサボり癖が出ちゃいましたw

インストール&ご感想もありがとうございます!大変励みになります😊

JboyHashimotoJboyHashimoto

短期間で課金機能までつけて開発したから天才ですね💙

よこよこ

Jboyさん

滅相もございません・・。
アプリならWebと違ってマーケットがあるので
それなりにダウンロードされるものだと思っていましたが、
やはり現実は甘くないですね・・💦