[Flutter] Flutterの各SDK(Flutter / iOS / Android)のバージョンをプロジェクトで指定したい

[Flutter] Flutterの各SDK(Flutter / iOS / Android)のバージョンをプロジェクトで指定したい

Clock Icon2025.06.11

こんにちは。きんくまです。

今回は「プロジェクトで使う各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のバージョン指定を行います。

参考用のリポジトリ

https://github.com/cm-tsmaeda/FlutterArchitectureRiverpod

Flutter SDK

Flutter SDKは、グローバルにインストールしたものではなく、各プロジェクトごとに指定のバージョンを使い分けます。

それをするために、FVMを使います。
https://fvm.app/

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
https://www.xcodes.app/

Xcodesをインストールすれば、以下のようにXcodeのリストが表示されるので、
そこからインストールしたり、きりかえたりできます。(右クリックでActiveを選ぶ)

flutter_sdk_250611_1

次はビルドできるSDKバージョンを固定します

ios/Runner.xcworkspace をXcodeで開きます

  1. 左のRunnerを選択
  2. TARGETSからRunnerを選択
  3. Build Phasesを選択
  4. +ボタンをクリック
  5. New Run Script Phaseを選択

flutter_sdk_250611_2

一番下に 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 <- 結果

flutter_sdk_250611_3

RECOMMEND_XCODE_VERSIONは今使っているXcodeのバージョンを書いておきます。

そこまで終わったら、スクリプトの実行順番を変えます。ドラッグして、もともとあったRun Scriptの上に入れておきましょう。

flutter_sdk_250611_4

これで、指定の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バージョンも指定しておくと良いと思います。

  1. ファイル一覧のRunnder
  2. TARGETSのRunnder
  3. General
  4. Minimum Deployments

flutter_sdk_250611_5

上のスクショだと16.6になっているので、iOS 16.6未満はインストールできないようになります。

Android SDK

Androidの場合は、Android SDKとgradleのバージョンが揃っていれば問題ないと思われます。
なので、Android Studioはメジャーバージョンが揃っていれば大丈夫だと思います。
(Androidはそこまで詳しくないため弱気です、、、)

Android Studioの過去のリリース一覧
https://developer.android.com/studio/archive
上のページは英語にしないとリンクが表示されませんでした。

上記のページから目的の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一覧
https://developer.android.com/guide/topics/manifest/uses-sdk-element#api-level-table

flutter_sdk_250611_6

例えば Android 15であれば、API levelは35なので、35を記載します。

ここで考慮することは、Flutter SDKのサポートするバージョンです。
https://docs.flutter.dev/reference/supported-platforms

flutter_sdk_250611_7

2025/06/11現在だと、Android SDKのSupported versionsは21-35、Unsupported versionsは20以下となっています。

もしAndroid 9以上はインストールできるようにするのであれば、minSdk=28となります。

上のページは最新のサポートバージョンしか載っていないのですが、Internet Archive使ったら一応昔のも確認できました
https://web.archive.org/web/20240215132311/https://docs.flutter.dev/reference/supported-platforms

ここまでで各SDKのバージョン指定の話は終わりです。
あとは、ライブラリのバージョン指定もpubspec.yamlでやっておくと良いと思います。(ゆらぎをもたせない)

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.