WHITEPLUS TechBlog

株式会社ホワイトプラスのエンジニアによる開発ブログです。

リネットのNativeアプリをFlutterでフルリニューアルしました!

この記事はWHITEPLUS Advent Calendar 2023の19日目の記事です。

こんにちは、アプリ開発グループでエンジニアを務めるdomonrです。 入社から約6ヶ月が経ち、この度自分が入社してから取り組んでいたFlutterを使用したアプリのフルリニューアルについての経験を共有したいと思います。

背景

このリニューアルプロジェクトを立ち上げた背景と目的は以下の通りです。

  • 開発効率の向上
    • Hot Reloadの利用
    • 宣言的なUIフレームワークの採用
    • Dart言語のみの使用で、SwiftやKotlinの言語コンテキストスイッチの削減
  • コミュニケーションコストの削減
  • ビジネス領域に集中しやすい環境の構築
  • 既存コードのフルリニューアル

個人的に最も重要だったのは、「既存コードのフルリニューアル」です。 歴史的な背景として、外注で作成したアプリを継ぎ足しで作成してきたこともあり、コードの設計や品質にばらつきが生じていました。共通コンポーネントに関しては、順序を変えると動作しない多層のIF文が存在し、リファクタリングも困難な状況でした。

リニューアルプロセスの概要

5月にプロジェクトを開始し、Flutterに慣れるためにホーム画面から着手しました。6月にはアーキテクチャーの検討を開始し、複雑ではないアプリのためできるだけ層を少なくする方針で進めました。7月にはログインや認証機能の実装に取り組み、ここで初めて既存実装の複雑さを実感しました。11月には開発を完了し、アプリをStoreにアップロードして審査を通過しました。そして、12月にリリースを迎えました。

苦労した点

Flutterのレイアウト

Flutterのレイアウトシステム(Constraints go down. Sizes go up. Parent sets position.)に慣れるのに時間がかかりました。特に、Widgetのサイズ設定が親に依存する点に慣れる必要がありました。

ネイティブ側の設定、実装

iOSには慣れていましたが、Androidに関しては以下の点で苦労しました。

  • Firebaseの環境別設定
    • Flutter用の設定ファイルと各種ネイティブの設定ファイルの両方が作成されるため両方を環境別に取り込むように設定が必要
  • build.gradleとAndroidManifest.xmlの理解
  • AndroidでのPush通知の設定
    • Push通知が表示されるがタップしてもアプリが起動できない
    • AndroidManifestの設定が間違っていた
  • Androidのリリース版での動作問題
    • 無事にproguardではまる
    • 入れていたライブラリが依存しているライブラリのproguard設定が必要だった
  • com.google.gms:oss-licensesに関する問題
    • 本番環境でのみ実際のライブラリ一覧が表示される(罠すぎる...)

Webview

webview_flutter(4系)を使用しましたが、以下の点で課題がありました。

  • get, postのハンドリング
    • 基本的にURLしか渡ってこないのでURLで全てを判断する必要がある
  • SafeAreaの対応
    • Webページ自体のページ下部などに余白が入っていないと端末の画面の下部までコンテンツが表示されてしまう
  • Webviewのちらつき問題
    • たまたまタイミングが悪かった話ですが、2週間ほど最新verでちらつきが発生しました
  • Flutter InAppWebViewを使っておいた方が無難そう
    • 静的ページを表示するだけなら不要ですが、ネイティブでできたことができなくて困る場合はFlutter InAppWebViewを使っておいた方が無難そうでした

Riverpod

Riverpodの2系から3系への移行期だったため、情報が古くなっていることが多く、学習に苦労しました。

  • 慣れるのに半年ぐらいかかった
  • 複雑なアプリじゃなかったら導入しなくてもいいと思った
    • 今回のアプリ規模だったらリニューアルのタイミングで導入しなくても必要になったタイミングで良さそうに感じた

Freezed

  • 記法になれるのに時間がかかった
  • partを指定しないとファイルが生成されない
  • g.dartはfromJsonがあると生成される

ライブラリ選定

  • MethodChannelが絡む一般的な機能のものに関してはライブラリを導入した
    • 個人的にはできるだけライブラリ使いたくない派なので若干抵抗あり
    • ただ、実装する場合に両OSの実装、メンテナンスコストを考えるとライブラリ導入したほうが良さそうと判断
    • in_app_review, flutter_app_badger, device_info_plus, package_info_plus, shared_preferences, uni_links, url_launcher等

Flutterフルリニューアルを振り返って

約半年間ほどリニューアルを行いましたが、実際の開発部分だけだと3ヶ月ぐらいで完了できたと思います。 既存のコードを全面的に作り直し、不要な処理の削除や仕様の簡素化を行うことができ、コードが読みやすくなりました。しかし、初のFlutter実装ということもあり、全体的に未熟な部分や分散したロジックが存在し、引き続きリファクタリングが必要です。

良かった点

  • Flutterの基本的な実装でつまづくポイントがほぼなくスムーズに開発できた
    • その分周辺でつまづくことは多いのだが...
  • AndroidとiOSの両方でビルドできるため、片方がうまくいかない場合でももう片方で動作確認が可能
  • HotReloadがありがたい、コード保存から2、3秒で更新される
  • Clean Build をする必要がない
  • CIのトータルの速度向上(別々に実行する必要がなくなったため)
  • Flutterコミュニティの活発さと勢い

困った点

  • セミコロンに慣れるのに時間がかかった
  • DartやFlutter、各種ライブラリの日々の変更が激しく、それに追いつくことが難しい

今後の展望

今回はAndroidとiOSアプリのリニューアルでしたが、Flutterを使えば異なるプラットフォームへの展開も可能です。個人的にはWeb版の提供もできたらいいなと考えています。