🌊

【Flutter】Flutter SDKのバージョンを 3.10.x にアップグレードした話

2023/07/23に公開

概要

私は「たびする」という旅行計画アプリをリリース・運用しております。
少し前に Flutter の 3.10.x がリリースされ、いろいろと大幅に変更されたので勉強も兼ねてアップグレードすることにしました。
この記事は、Flutter と各パッケージをアップグレードした時に、調べたこと、やったことを備忘録として書いたものになります。

想定読者

  • Flutter のバージョンを 3.10.x にアップグレードを検討しているがやり方がわからない
  • パッケージをアップグレードする方法が知りたい

アップグレード

アップグレードは下記の順番で実施していきます。

  1. Flutter のアップグレード
  2. パッケージ(マイナーバージョン)のアップグレード
  3. パッケージ(メジャーバージョン)のアップグレード

1. Flutter のバージョンを変更

私のプロジェクトでは fvm を使用しております。

fvm を使用していない方

fvm を使用していない方は、下記コマンドで Flutter SDK の最新バージョンを取得することができます。

ターミナル
flutter upgrade

最新バージョンを取得したら、この章は飛ばしてください。

まずは fvm releases で現在リリースされている Flutter のバージョンを確認します。

ターミナル
Jun 7 233.10.4           
Jun 8 233.12.0           
Jun 14 233.10.5           
Jun 21 233.12.0-1.1.pre   
Jul 12 233.13.0-0.1.pre   
--------------------------------------
Jul 12 233.10.6            stable
--------------------------------------
--------------------------------------
Jul 19 233.13.0-0.2.pre    beta
--------------------------------------

stable のバージョンを使用したいので fvm use 3.10.6 を実行します。
すると、fvm_config.json ファイルが下記のように変更されました。

{
-  "flutterSdkVersion": "3.7.0",
+  "flutterSdkVersion": "3.10.6",
  "flavors": {}
}

この状態で一度 cleanget を実行します。

ターミナル
fvm flutter clean
fvm flutter pub get

すると下記エラーが発生しました。

ターミナル
fvm flutter pub get
Resolving dependencies...
Because プロジェクトの名前 depends on flutter_localizations from sdk which depends on intl 0.18.0, intl 0.18.0 is required.
So, because プロジェクトの名前 depends on intl ^0.17.0, version solving failed.

flutter_localizations パッケージが intl 0.18.0 に依存しているようなので pubspec.yaml を以下のように変更しました。

pubspec.yaml
# 中略

environment:
-  sdk: ">=2.17.6 <3.0.0"
+  sdk: ">=3.0.0 <4.0.0"

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
-  intl: ^0.17.0
+  intl: ^0.18.0

# 中略

再び fvm flutter pub get を実行するとうまくいきました。

余談
この時点で fvm dart fix --apply を実行すると、ExpandedColumn などに const がつきました。
また、 switch 文の break も一部削除されました。
詳しくは Flutter 3.10.0 release notes に記載がありますのでご確認ください。

2. パッケージのアップグレード(マイナーバージョン)

ここからは公式ドキュメントを参考にパッケージのアップグレードをしていきます。

まずは各パッケージのマイナーバージョンをアップグレードします。
マイナーバージョンはアップグレードしたとしても、破壊的変更は含まれていないのでアプリは正常に動作します。

それでは下記コマンドを実行し、パッケージのマイナーバージョンをアップグレードします。

ターミナル
fvm flutter pub upgrade
fvm flutter clean
fvm flutter pub get

その後アプリをデバッグモードで起動し、ビルドできるまでエラーを修正していきます。

発生したエラー

1. Firebase/Firestore (= 10.12.0)に依存

Podfile を修正

Podfile
# 中略

target 'Runner' do
  use_frameworks!
  use_modular_headers! 

-  pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '10.9.0'
+  pod 'FirebaseFirestore', :git => 'https://github.com/invertase/firestore-ios-sdk-frameworks.git', :tag => '10.12.0'

  flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end

# 中略

下記を実行

ターミナル
cd ios/
pod repo update
pod update
flutter_datetime_picker パッケージ

エラー内容

Error (Xcode): ../../.pub-cache/hosted/pub.dev/flutter_datetime_picker-1.5.1/lib/flutter_datetime_picker.dart:6:1: Error: 'DatePickerTheme' is imported from both 'package:flutter/src/material/date_picker_theme.dart' and 'package:flutter_datetime_picker/src/datetime_picker_theme.dart'.

flutter_datetime_pickerパッケージが更新されておらず、DatePickerTheme クラスが競合
issue を確認するとフォークした新しいパッケージ flutter_datetime_picker_plus があるとのことでこちらを使用

pubspec.yaml
# 中略
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
    
-  flutter_datetime_picker: ^1.5.1
+  flutter_datetime_picker_plus: ^2.0.1

# 中略
macos_ui パッケージ

エラー内容

Error (Xcode): ../../.pub-cache/hosted/pub.dev/macos_ui-1.12.2/lib/src/fields/text_field.dart:108:35: Error: The parameter 'details' of the method '_TextFieldSelectionGestureDetectorBuilder.onSingleTapUp' has type 'TapUpDetails', which does not match the corresponding type, 'TapDragUpDetails', in the overridden method, 'TextSelectionGestureDetectorBuilder.onSingleTapUp'.

こちらのエラーは別記事にて解説しましたのでそちらをご覧ください。
https://zenn.dev/namioto/articles/9a82de6acb8f2e

flutter_neumorphic パッケージ

エラー内容

Error (Xcode): ../../.pub-cache/hosted/pub.dev/flutter_neumorphic-3.2.0/lib/src/widget/app_bar.dart:183:29: Error: The getter 'textTheme' isn't defined for the class 'AppBarTheme'.

こちらも flutter_datetime_picker 同様、パッケージが更新されておらず、 textTheme が定義されていないというエラーが発生しています。
issue を確認するとパッケージをフォークして修正されている方がいらっしゃったのでそちらを使用させていただきます。

pubspec.yaml を変更し、再度ビルドすると直ります。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter

-  flutter_neumorphic: ^3.2.0
+  flutter_neumorphic:
+    git:
+      url: https://github.com/den0206/Flutter-Neumorphic.git
+      ref: feature/remoce_accentcolor

ここまで修正することとビルドができるようになりました👏

3. パッケージのアップグレード(メジャーバージョン)

ここからは flutter pub upgrade --major-versions を使用して、パッケージのメジャーバージョンをアップデートをしていきます。

各パッケージの CHANGELOG を1つ1つ確認し、コードの修正が必要であれば修正...の繰り返しです。

それでは早速コマンドを...といきたいところですが、先日参加させていただいた FlutterGakkai のツルオカ(@h_tsuruo)さんの発表で紹介されていた、mono さんの CHANGELOG をブラウザで一斉に開いてくれるスクリプトが便利そう + grinder を使用したことがなく、便利そうだったのでそちらを導入していきます。

grinder の導入はこちらを参考にさせていただきました。
https://zenn.dev/k9i/articles/bcfa83b08e56d6

grinder の導入ができたら、パッケージのメジャーバージョンをアップデートし、grinder を使用して各パッケージの ChagneLog を開きます。

ターミナル
fvm flutter pub upgrade --major-versions
grind open-upgraded-package-changelog

grind open-upgraded-package-changelog を実行すると、ブラウザでアップグレードされた各パッケージの CHANGELOG が表示されるので、1つ1つ確認し、コードの変更が必要な箇所は修正していきます。

これでパッケージのアップグレードが完了しました!

ios Android それぞれでビルドしてみる

Flutter と各パッケージのアップグレードが完了したので、ios、Android ともにビルドできるようになるまでビルドエラーを修正していきます。
今回は ios、Android で1つずつしかエラーが発生しなかったのですぐ終わりました。

ios ビルドエラー

ios ビルドで下記のエラーが発生しました。

Error: CocoaPods's specs repository is too out-of-date to satisfy dependencies.

このエラーを解消するため、下記を実行します。

ターミナル
cd ios/
pod repo update
pod update
cd ../
fvm flutter clean
fvm flutter pub get

無事 ios でビルドできるようになりました👏

Android ビルドエラー

Android ビルドで下記のエラーが発生しました。

ターミナル
BUILD FAILED in 32s
┌─ Flutter Fix ──────────────────────────────────────────────────────────────────────────────┐
│ [!] Your project requires a newer version of the Kotlin Gradle plugin.                     │
│ Find the latest version on https://kotlinlang.org/docs/releases.html#release-details, then │
│ update /project/to/path/android/build.gradle:                                              │
│ ext.kotlin_version = '<latest-version>'                                                    │
└────────────────────────────────────────────────────────────────────────────────────────────┘

kotlin のバージョンをアップグレードする必要があるみたいです。
エラーに記載のある通りドキュメントで kotlin の最新バージョンを確認し build.gradle ファイルを修正します。
確認したところ、執筆時点では 1.9.0 が最新版なので、このバージョンに変更します。
build.gradle を編集します。

build.gradle
buildscript {
- ext.kotlin_version = '1.6.21'
+ ext.kotlin_version = '1.9.0'
repositories {
    google()
    mavenCentral()
}
// ...

無事 Android でもビルドができるようになりました👏

まとめ

思ったよりも簡単に Flutter と各パッケージのアップグレードができました。
私の想像ではエラーが大量に発生して頭を悩ませながら数日かかる...と思っていたのでよかったです笑

アップグレードするメリットは少なくとも

  1. パフォーマンス、セキュリティの向上
  2. 開発者体験の向上(新しい構文、ワイヤレスデバックなど)
  3. CHANGELOG を確認することでスキル・知識の向上につながる

はあると思います。

今回アップグレードしたアプリは個人開発のアプリなのでメリットに含めませんでしたが、新しい技術をどんどん導入している会社にはレベルの高いエンジニアが集まりやすいとも思います🤔

わかりやすい例だと「riverpod ではなく provider を使用している」などでしょうか?(コスト面で仕方ない部分はあると思います。)
私自身、アサイン先が古い開発環境(Flutter やパッケージのバージョンが低い、すでにメンテナンスされていないパッケージを使用しているなど)だとテンションが上がらない感は否めません。
そういう意味でも常に開発環境をアップデートするメリットは大きいと思います。

長くなりましたが、今後はパッケージアップのグレードや CHANGELOG を定期的に確認する癖をつけて、よりスキルアップできるようにしていきたいです!

以上です。

GitHubで編集を提案

Discussion