BETA

Flutter初心者が10日間でクロスプラットフォームアプリを開発・リリースしたみた。

投稿日:2020-08-05
最終更新:2020-08-07

Flutter+Firebaseを使い、Android, iOSをクロスプラットフォームアプリとして10日くらいで友人と共同で開発してリリースしたのでその過程、問題、感想を書きます。

僕について。

色んな言語に手を出しつつ結局極めたものがそんなない情報系大学生。Railsのエンジニアインターンを半年と、スペインバルでのバイトに出勤したらお店の前に「破産しました」という紙が貼られていた経験があります。
お金がないので業務委託もしくはインターンとして働ける先を切実に探しています。
連絡はこちらのDMまで。Twitter

作ったもの

Kpop のニュースを好きなアーティストごとに見れるキュレーションアプリです。

  • アーティストを選択すると自分だけのタイムラインが作れる。
  • アーティストごとにも見れる
  • お気に入りできる。

Android: Google Play

技術選定理由

Flutter

クロスプラットフォーム開発できる、それだけで選びました。初めて触りましたが、SwiftUIを少し勉強したこともあり、宣言的UIシステムの概念はわかっていたのですんなり開発できました。

Dartに関しては、Javaに似ているけど async await はJSと一緒だったり、と今までの経験から難しくはなかったです。これをやる前に関数型言語を学んでいたので、副作用については結構敏感になっていました。標準のライブラリで肝心な関数が参照渡しでvoidだったりして割と萎えました。sortとか。

Firebase

みんな大好きFirebase!初めてまともに使いました。FireStoreがベータ版だったときちょろっと触って、ドキュメントが全然なくて投げた記憶があります。

FireStore, Authentication を使いました。今は基本端末だけで動いていますが、これからFunctionsでバックエンドを作っていきます。

Flutterのライブラリがあるので簡単に導入できます。最初の方は無料で使えるプランがあり、有料でも事前に見積もりが簡単にできます。

アプリでは、Authenticationで匿名認証を行い、Firestoreで好きなアーティストリストなどと紐付けて管理しています。将来的にSNS機能を追加するときもソーシャルログインが簡単にできます。こんなに簡単に使えるなんて、Google様に感謝してもしきれません。

過程

最初は何から手をつけていいのか本当に分からなかったので、とりあえず「Flutter 作り方」とかで調べてました。いろいろ調べた結果、状態管理は Provider が推奨されているんだなーとか、基本 Stateless Widget を使おう(結局Statefullも使うことになる)とか決めました。

ディレクトリ構造

まず手をつけたのはディレクトリ構造でした。MVVM + DDD的な感じにしようと思い、Flutterに限らず、参考になるプロジェクト構造の例を探しました。

参考になったのはこちら。構造を結構パク真似しました。
https://kabochapo.hateblo.jp/entry/2019/11/21/160759
https://at-sushi.work/blog/3
https://medium.com/incresco/flutter-scalable-app-folder-structure-6f2b0bc139c4

最終的にこんな感じのディレクトリになりました。commonとかconfigとかutilsとかいつ使うんでしょうね。

lib/  
├── common  
├── config  
├── main.dart  
├── models  
│   ├── artist.dart  
│   ├── news.dart  
│   ├── news_vm.dart  
│   ├── publisher.dart  
│   └── user.dart  
├── providers  
│   ├── news_item_provider.dart  
│   ├── news_list_provider.dart  
│   ├── select_artist_provider.dart  
│   └── user_provider.dart  
├── services  
│   ├── RssReader.dart  
│   └── firebase_auth_service.dart  
├── utils  
└── views  
    ├── artist_search_view.dart  
    ├── home.dart  
    ├── news  
    │   ├── news_item_view.dart  
    │   ├── news_list_view.dart  
    │   ├── news_search_view.dart  
    │   └── news_view.dart  
    ├── select_artist.dart  
    └── user.dart  

完璧なDDD(ドメイン指向開発)をやりたかったのですが、コードを書いているうちにライブラリや言語に依存してロジックが分散していくようになってしまいました。。コードレビューしてくれる人マジで募集中です。形式的にやって無駄なコードが増えても良くないので、ある程度我流で省略してロジックがなんとかまとまるようにしました。

DDDはドメイン指向という思想で、クリーンアーキテクチャはコーディングの姿勢だと思っています。もっとサンプルコードを読んで書いて勉強しないとこのままではこのアプリがカルボナーラになってしまいます。

Statefull か Statelessか

Future Builder

基本Stateless+Providerでやるつもりでしたが、FutureBuilder Widget は Stateless だとなぜか子Widigetを変更した時に毎回呼ばれてしまい、値の更新とともに画面更新が起こってしまってました。StatefullにするとProviderの値だけ更新されるようになりました。仕方ないのでStatefullにしました。

動的なTab変更

アーティストを選択した時、タブの種類が増えるような仕様です。ここが難しくて、動的なtabの変更はエラーが起こるようだったので、Statefull Widgetの中で、TabControllerを状態としてもち、データの個数が変わった時だけ新しく作り直したらエラーがなくなりました。UIの状態だしView側で管理しても問題ないかーと勝手に納得しました。

その他、RSSパーサーをメディア別にゴリゴリ書いたり、「map関数はIterative Objectを返すだけで、呼んだだけじゃ中身が実行されないlazyな関数」というのを知らなくてハマって半日かかったり効率悪いことしてました。

リリース

アイコン素材は友人に作ってもらい、flutter_launcher_icons を使ってiOS、Android用のアイコンを生成しました。背景と前景だけ用意すればいいので楽チンです。

利用規約とプライバシーポリシーはいろんなサービスを参考にして書きました。

ライブラリ表記は、Flutterには showLicencePage という便利な関数があり、ライブラリの著作権表記ページを自動生成してくれるのでこれを使いました。

二人で開発したので、企業アカウントがないとiOS片方しか実機ビルドできない、という問題があり、不便でした。Androidを二人とも持っていないので、実機確認ができないのも割と痛かったです。

感想

コードを理想のように綺麗に書くことはできませんでしたが、まずは動くコードを作るのが先。リリースができて本当に嬉しいです。これから実装した機能が山ほどあるので、機能拡張とともにリファクタリングも進めていきます。

アプリ開発自体はビジネスの始まりにすぎないので、これからはアプリのマーケティングもユーザーの声を聞きながら力を注いでいきます。

読んでくれてありがとうございます。

技術ブログをはじめよう Qrunch(クランチ)は、プログラマの技術アプトプットに特化したブログサービスです
駆け出しエンジニアからエキスパートまで全ての方々のアウトプットを歓迎しております!
or 外部アカウントで 登録 / ログイン する
クランチについてもっと詳しく

この記事が掲載されているブログ

よく一緒に読まれる記事

0件のコメント

ブログ開設 or ログイン してコメントを送ってみよう