![[Flutter] Flutterの各SDK(Flutter / iOS / Android)のバージョンをプロジェクトで指定したい](https://images.ctfassets.net/ct0aopd36mqt/wp-thumbnail-97bd004eb227348cf028ece41fd4689e/b36c0bd625924c92c33ad88396cb5f71/flutter.png)
[Flutter] Flutterの各SDK(Flutter / iOS / Android)のバージョンをプロジェクトで指定したい
こんにちは。きんくまです。
今回は「プロジェクトで使う各SDKのバージョンを指定したい」です。
SDKというのは以下になります。
- Flutter SDK
- iOS SDK
- Android SDK
これらをバージョン指定をして、チームの誰がビルドしても同じ環境になるようにしたいです。
以前にあったこと
どうしてバージョン指定をしたいのかを先に説明します。
以前にこんなことがありました。
その1: iOSアプリで、Xcodeのマイナーバージョン(真ん中の数字。例えば16.x.0)をアップしただけで、挙動が変わってしまった。
Xcodeのマイナーバージョンだけをアップして、アプリを本番リリースしました。
そうしたら、画面一部が白くなっている(何も表示されていない)ことに気が付かず、お客様より連絡が入り気が付くことになりました。
そのときの更新内容とは全く無関係で、ソースコードも全く触っていない部分でした。
Xcodeのバージョンアップをしたときは、エラーも警告も出ていませんでした。
原因は、jsonのパースまわりの挙動がXcodeのバージョンをあげただけで変わっていました。(調べたらリリースノートには出ていた)
このときは、休日対応することになり、お客様にもチームメンバーにも迷惑をかけまして、反省しました。
その2: Firebase SDKのバグで、プッシュ通知が届かない状態になっていた
Firebase SDKのバージョンをあまり気にせずアップしていたのですが、プッシュ通知が届いていないことに気が付きませんでした。
タスクキル状態からアプリを立ち上げたあと、バックグラウンドに移行したとき(初回)は、プッシュ通知が届くのですが、2回目以降にバックグラウンド状態になったときは、プッシュ通知が届かないという、見つけにくいバグでした。
原因はFirebase SDKのバグで、SDKアップデートだけでなく、内部的に追加対策をいれる必要がありました。
以上の経験から、バージョンアップに対してはかなり慎重になっていて、今のプロジェクトだとSDKやライブラリのアップデートは1年に1度のみ。開発とテストの工数をとって対応することにしています。
またチーム開発の場合は、誰かの環境だとおきるけど、誰かの環境だとおきないバグというものが出そうです。そのため、SDKとライブラリのバージョンは固定するのが良いと思っています。
(それで、数ヶ月や1年に1度といった定期的に工数をとってアップデート対応を行う)
ということをふまえて、各SDKのバージョン指定を行います。
参考用のリポジトリ
Flutter SDK
Flutter SDKは、グローバルにインストールしたものではなく、各プロジェクトごとに指定のバージョンを使い分けます。
それをするために、FVMを使います。
FVMを使えば以下が可能になります。
- プロジェクトごとのFlutter SDKのバージョン指定
- Flutter SDKの複数バージョンインストール
公式のインストール後にfvmコマンドが使えるようになります。
リリース済みのSDKの確認
fvm releases
┌───────────────────┬──────────────┬──────────┐
│ Version │ Release Date │ Channel │
├───────────────────┼──────────────┼──────────┤
│ v1.0.0 │ Dec 4, 2018 │ stable │
├───────────────────┼──────────────┼──────────┤
│ v1.2.1 │ Feb 26, 2019 │ stable │
├───────────────────┼──────────────┼──────────┤
│ v1.5.4-hotfix.2 │ May 7, 2019 │ stable │
├───────────────────┼──────────────┼──────────┤
省略
├───────────────────┼──────────────┼──────────┤
│ 3.32.0 │ May 20, 2025 │ stable │
├───────────────────┼──────────────┼──────────┤
│ 3.32.1 │ May 29, 2025 │ stable │
├───────────────────┼──────────────┼──────────┤
│ 3.32.2 │ Jun 4, 2025 │ stable ✓ │
└───────────────────┴──────────────┴──────────┘
SDKのインストール
fvm install バージョン番号
例
fvm install 3.32.1
ローカルにインストールされているSDKの確認
fvm list
┌─────────┬─────────┬─────────────────┬──────────────┬──────────────┬────────┬───────┐
│ Version │ Channel │ Flutter Version │ Dart Version │ Release Date │ Global │ Local │
├─────────┼─────────┼─────────────────┼──────────────┼──────────────┼────────┼───────┤
│ 3.32.1 │ stable │ 3.32.1 │ 3.8.1 │ May 29, 2025 │ │ ● │
├─────────┼─────────┼─────────────────┼──────────────┼──────────────┼────────┼───────┤
│ 3.29.2 │ stable │ 3.29.2 │ 3.7.2 │ Mar 13, 2025 │ │ │
├─────────┼─────────┼─────────────────┼──────────────┼──────────────┼────────┼───────┤
省略
SDKをインストールしたあとは、プロジェクトのルートに入ったあとに、以下のコマンドでバージョン指定が行えます。
fvm use バージョン番号
例
fvm use 3.32.1
fvm use実行時に 「.fvmディレクトリをgit管理からはずすから、gitignoreに追加するか?」と聞かれるのでy(yes)で回答します
You should add the fvm version directory ".fvm/" to .gitignore.
✔ Would you like to do that now? · yes
インストールすると以下が追加されます
.fvmディレクトリ
.fvmrc
.gitignoreには以下が追加されています
# FVM Version Cache
.fvm/
注意点!
fvmインストール後の注意点としては、コマンドのflutterコマンドやdartコマンドを実行する前に必ずfvmのコマンドをつける必要があります
NG
flutter run
OK
fvm flutter run
pubspec.yaml
pubspec.yamlにもバージョン指定を行います
environment:
sdk: ^3.8.1
flutter: 3.32.1
sdkはDartのバージョンです。以下のコマンドで確認できます。
fvm dart --version
結果
Dart SDK version: 3.8.1 (stable) (Wed May 28 00:47:25 2025 -0700) on "macos_arm64"
flutterは、インストールしているFlutter SDKのバージョンです
iOS SDK
iOS SDKはXcodeと密接に結びついています。
まずはXcodeを複数バージョン管理できるようにします。
それができるツールはいろいろとあると思うのですが、自分はXcodesを使っています。
Xcodes
Xcodesをインストールすれば、以下のようにXcodeのリストが表示されるので、
そこからインストールしたり、きりかえたりできます。(右クリックでActiveを選ぶ)
次はビルドできるSDKバージョンを固定します
ios/Runner.xcworkspace をXcodeで開きます
- 左のRunnerを選択
- TARGETSからRunnerを選択
- Build Phasesを選択
- +ボタンをクリック
- New Run Script Phaseを選択
一番下に Run Scriptが追加されるので、中を編集します
タイトル(好きなようにつけてください):
Run Script (iOS SDK check)
中身
#!/bin/bash
# iOS SDKのバージョン
REQUIRED_SDK_VERSION="18.2"
# インストールするXcodeのバージョン
RECOMMEND_XCODE_VERSION="16.2"
CURRENT_SDK_VERSION=$(xcrun --sdk iphoneos --show-sdk-version)
if [ "$CURRENT_SDK_VERSION" != "$REQUIRED_SDK_VERSION" ]; then
echo "Error: iOS SDK version $REQUIRED_SDK_VERSION is required, but $CURRENT_SDK_VERSION is available."
echo "Current Xcode installation provides iOS SDK $CURRENT_SDK_VERSION,"
echo "Recommend Xcode version is $RECOMMEND_XCODE_VERSION"
exit 1
fi
echo "✅ Using correct iOS SDK version: $CURRENT_SDK_VERSION"
REQUIRED_SDK_VERSIONの値は、Terminalなどで以下のコマンドを打ちます。これが、いまのXcodeで使っているiphonos SDK=iOS SDKのバージョンです。
xcrun --sdk iphoneos --show-sdk-version
18.2 <- 結果
RECOMMEND_XCODE_VERSIONは今使っているXcodeのバージョンを書いておきます。
そこまで終わったら、スクリプトの実行順番を変えます。ドラッグして、もともとあったRun Scriptの上に入れておきましょう。
これで、指定のXcodeとiOS SDKの組み合わせのみビルドが通るようになりました。(他はビルドが通らない)
オプション(CocoaPodsのバージョンを揃える)
これはオプションで、やってもやらなくても良いと思いますが、参考までに書きます。
Flutter公式の開発ではCocoaPodsからSwift Package Manager(SPM)に切り替える開発をしている途中とのことですが、現在はCocoaPodsを使っています。
同じチーム内で、CocoaPods自体のバージョン番号が違うと、ビルドが通らなかったりdiffが出ることがあります。
なので、CocoaPodsのバージョンを揃えます。
Bundlerというツールで管理します。Bundlerをインストール
bundler自体のバージョンは揃えなくても大丈夫だと思います。
gem install bundler --no-document --version '= 2.3.7'
プロジェクトルートに、Gemfileというファイルを追加します
Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem "cocoapods", "1.16.2"
インストールコマンドを実行します。
bundle config set --local path 'vendor/bundle'
bundle install
このあとは、iOSプロジェクトであれば以下のようなコマンドでPodファイルをインストールできます。
通常のコマンド pod の前に bundle exec が追加で入るイメージです。
(Podファイルを使わないのであれば不要に実行しなくて良いです。)
bundle exec pod install --repo-update
ここで、BundlerバージョンのCocoaPodsを実行するにあたり、Flutter SDKを一部修正する必要があります。
cocoapods.dartを修正するためにファイルを開きます
${FlutterSDKインストール先}/packages/flutter_tools/lib/src/macos/cocoapods.dart
FlutterSDKインストール先は以下でした
~/fvm/versions/{Flutter SDK バージョン番号}
修正箇所は4箇所あります。
修正するポイントは、さきほど説明したみたいに、 'bundle', 'exec' をコマンドの前に追加することです。
Future<bool> get isInstalled =>
//_processUtils.exitsHappy(<String>['which', 'pod']);
_processUtils.exitsHappy(<String>['bundle', 'exec', 'which', 'pod']); // ここ!
Future<String?> get cocoaPodsVersionText {
_versionText ??= _processUtils.run(
//<String>['pod', '--version'],
<String>['bundle', 'exec', 'pod', '--version'], // ここ!
environment: <String, String>{
'LANG': 'en_US.UTF-8',
},
中略
//final Status status = _logger.startProgress('Running pod install...');
final Status status = _logger.startProgress('Running bundle exec pod install...'); // ここ!
final ProcessResult result = await _processManager.run(
//<String>['pod', 'install', '--verbose'],
<String>['bundle', 'exec', 'pod', 'install', '--verbose'], // ここ!
workingDirectory: _fileSystem.path.dirname(xcodeProject.podfile.path),
修正後にキャッシュを削除します
${FlutterSDKインストール先}/bin/cache/flutter_tools.snapshot
この状態にすると、flutter doctorコマンドが通ります
fvm flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.32.1, on macOS 15.3.2 24D81 darwin-arm64, locale en-JP)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] Android Studio (version 2024.1)
[✓] VS Code (version 1.100.3)
[✓] Connected device (5 available)
[✓] Network resources
• No issues found!
あと.gitignoreに以下のものを足しておくと良いと思います
# Bundler for CocoaPods
Gemfile.lock
/vendor/
/.bundle/
参考)こちらの記事を参考にさせてもらいました!
Flutter の CocoaPods を rbenv と bundler で管理する
インストール可能な最小OSバージョン
あと、インストール可能な最小OSバージョンも指定しておくと良いと思います。
- ファイル一覧のRunnder
- TARGETSのRunnder
- General
- Minimum Deployments
上のスクショだと16.6になっているので、iOS 16.6未満はインストールできないようになります。
Android SDK
Androidの場合は、Android SDKとgradleのバージョンが揃っていれば問題ないと思われます。
なので、Android Studioはメジャーバージョンが揃っていれば大丈夫だと思います。
(Androidはそこまで詳しくないため弱気です、、、)
Android Studioの過去のリリース一覧
上のページは英語にしないとリンクが表示されませんでした。上記のページから目的のAndroid Studioをインストールします。
Andorid SDKのバージョンを指定する
android/app/build.gradle.kts
修正前
android {
namespace = "com.sample.myapp.app250611"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.sample.myapp.app250611"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
修正後
android {
namespace = "com.sample.myapp.app250611"
// Android 15
compileSdk = 35 // ここです!
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.sample.myapp.app250604"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
// Android 9
minSdk = 28 // ここです!
targetSdk = 35 // ここです!
versionCode = flutter.versionCode
versionName = flutter.versionName
}
compileSdkとdefaultConfig.targetSdk
-> Flutter SDKでサポートしている最新バージョンを書く。(基本は同じバージョン)
defaultConfig.minSdk
-> インストールできる最小のバージョンを書く
ここで指定するバージョンなのですが、Android OSバージョンとは違うAPI levelのバージョンを書きます。
API level一覧
例えば Android 15であれば、API levelは35なので、35を記載します。
ここで考慮することは、Flutter SDKのサポートするバージョンです。
2025/06/11現在だと、Android SDKのSupported versionsは21-35、Unsupported versionsは20以下となっています。
もしAndroid 9以上はインストールできるようにするのであれば、minSdk=28となります。
上のページは最新のサポートバージョンしか載っていないのですが、Internet Archive使ったら一応昔のも確認できました
ここまでで各SDKのバージョン指定の話は終わりです。
あとは、ライブラリのバージョン指定もpubspec.yamlでやっておくと良いと思います。(ゆらぎをもたせない)