iOSのArchiveが突然失敗し、プラグインのモジュールも見つからない。
最短の解決策は、Flutter 3.47でSwift Package Managerを標準経路として試しつつ、未対応プラグインはCocoaPodsへ残し、隔離したMacでArchiveとTestFlightを確認してから本番のビルド環境を切り替えることです。

この手順を読むべき人

Flutterの旧版から3.47へ更新し、iOS公開を止めたくない個人開発者向けの記事です。
複数のネイティブプラグインを利用していて、Swift Package Managerへの対応状況を把握できていないプロジェクトにも適しています。

WindowsやLinuxを主な開発環境にしており、iOSのビルドと公開だけをリモートMacで行う小規模チームも対象です。

Flutter 3.44以降、Swift Package ManagerはiOSとmacOSのネイティブ依存関係を扱う標準の方式になりました。一方で、互換性のない依存関係はCocoaPodsへ戻せる設計です。したがって、既存のPodfileを最初から削除するのではなく、二つの経路を比較できる状態で移行します。

Flutter公式のSwift Package Manager移行ガイドでも、対応していない依存関係を確認しながら段階的に扱う考え方が示されています。

最終更新:2026年9月17日。Flutter 3.47の安定版情報、Swift Package Managerの移行仕様、iOS公開手順、App Store Connectのビルド状態を公式資料で再確認しています。

移行前に「公開できる状態」を固定する

最初に行うのは、依存関係の変更ではなく回復地点の保存です。Flutter SDKのバージョン、Xcodeの選択状態、依存ロックファイル、Podfile、署名方式、Bundle ID、Team IDを記録し、最後に成功したArchiveの識別情報を安全な場所へ保存します。

証明書、秘密鍵、App Store Connectの認証情報は記事やログへ貼り付けず、値を伏せた変数名だけを記録してください。プロジェクト名、Bundle ID、Team ID、証明書名も、共有用ログでは必ず置き換えます。

保存対象 移行前に確認する内容 失敗時の用途
Flutter SDK 実行しているSDKのパスとバージョン 同じSDKへ戻す
依存定義 pubspec.yaml、ロックファイル、Podfile 依存解決を再現する
Xcode設定 選択中のXcode、Workspace、Scheme Archive環境を戻す
公開設定 署名方式、Export設定、認証方式 IPA出力を再構成する
成功記録 最後に通ったArchiveとログ 新旧結果を比較する

次のように、実行アカウント、プロジェクトディレクトリ、SDKパスを明示して記録します。以下は匿名化した例です。

# 実行アカウント: build-user
# プロジェクト: /Users/build-user/work/sample_app
# Flutter SDK: /Users/build-user/tools/flutter
cd /Users/build-user/work/sample_app
/Users/build-user/tools/flutter --version
/Users/build-user/tools/flutter pub get

期待する結果は、SDK情報が記録され、依存取得が終了コード0で完了することです。既存環境を上書きする前にブランチを作成し、撤回するときは移行用ブランチを破棄して保存済みのリリースブランチへ戻します。

注意:唯一の本番用Macで先に実行すると、生成されたXcode設定や依存キャッシュの差分を切り分けにくくなります。初回移行は別のMac、または本番から分離したリモートMacで行ってください。

最初の1時間でプラグインを分類する

pubspec.yamlの依存一覧だけでは、iOSネイティブコードの有無や導入方式までは判断できません。Flutterの依存ツリー、iOS側のログ、プラグインの公式ドキュメントを組み合わせ、各プラグインを次の三つに分類します。

分類 確認する証拠 当面の処理
SwiftPM対応 公式の対応記載、生成されたPackage参照、正常な解決ログ SwiftPM側で検証
CocoaPods継続 Podfile独自設定、ローカルPod、未対応のネイティブ依存 CocoaPodsへ回退
要調査 私有Spec、手動Framework、独自スクリプト 変更せず隔離環境で確認

特に見落としやすいのは、手書きのPodfile設定、ローカルPod、私有Spec、手動で追加したFramework、ビルドフェーズのスクリプトです。プラグインがSwiftPMに対応していても、プロジェクト側の独自設定がPodsを前提にしていれば、単純な置換ではArchiveまで進みません。

Flutterのプラグイン開発資料では、iOS側のネイティブ実装や依存関係の扱いが説明されています。プラグインを一括で移行するのではなく、Flutterのプラグイン構成に関する公式資料を参照しながら、ライブラリ単位で担当方式を決めてください。

SwiftPMを初回接続し、生成差分を読む

分類が終わったら、移行用ブランチで依存取得を実行し、XcodeのWorkspaceまたはプロジェクトにどのような参照が生成されたかを確認します。見るべきなのは、パッケージ参照、プラグイン登録、ビルドフェーズ、最小OSバージョン、リンク対象の重複です。

# 実行アカウント: build-user
# 作業場所: /Users/build-user/work/sample_app
# Flutter SDK: /Users/build-user/tools/flutter
cd /Users/build-user/work/sample_app
/Users/build-user/tools/flutter clean
/Users/build-user/tools/flutter pub get
open ios/Runner.xcworkspace

期待する結果は、依存解決が完了し、Xcodeで対象Schemeを開けることです。ここではまだ配布用署名を行いません。まずSimulator向け、または署名を必要としない基本ビルドで、パッケージ解決、プラグイン登録、コンパイルが完了するかを確認します。

# 実行アカウント: build-user
# 作業場所: /Users/build-user/work/sample_app
cd /Users/build-user/work/sample_app
/Users/build-user/tools/flutter build ios --debug --no-codesign

成功の判断は、単にコマンドが終了することではありません。対象プラグインのAPIを呼び出す画面まで動かし、ログにモジュール未検出、リンク失敗、登録漏れがないことを確認します。戻す場合は、生成物を保存したうえで移行前ブランチへ戻し、保存済みのロックファイルとPodfileを使います。

二つの依存経路を混在させる条件

SwiftPMとCocoaPodsは移行期間に併用できます。ただし、同じネイティブライブラリを双方から読み込ませてはいけません。併用する場合は、プラグインごとに管理方式を表へ固定し、担当方式が変わった理由も記録します。

判断は次の条件分岐で行います。

  • 公式にSwiftPM対応があり、クリーンな依存解決と基本ビルドが通るなら、SwiftPM側で継続します。
  • SwiftPM未対応で、Podfileの設定だけで正常に組み込めるなら、そのプラグインはCocoaPodsへ回退します。
  • 同一ライブラリの重複読み込みが疑われるなら、先に片方の参照を外し、再度依存ツリーを確認します。
  • 重複シンボルが出た場合は二重導入を疑い、モジュールが見つからない場合は担当方式と生成参照を確認します。
  • 最小OSバージョンの衝突なら、プラグインの要求値を比較し、無理に第三者プラグインのソースを改変しません。
  • リモートパッケージ取得に失敗した場合は、キャッシュを成功の証拠とみなさず、クリーン環境で再取得できるかを確認します。

SwiftPMを使うこと自体を目的にすると、対応していないプラグインのソースを直接改造する判断に傾きます。公開を止めないことが目的なら、未対応部分を一時的にCocoaPodsへ残し、次のプラグイン更新時に再評価するほうが安全です。

経験則:Debugビルドが通っても、署名、Release最適化、Archive、TestFlightのインストールまで成功したとは限りません。移行完了の判定を「コンパイル成功」だけに設定しないでください。

リモートMacとCIで同じ環境を再現する

WindowsやLinuxでDartコードを編集していても、iOSの依存解決、Xcodeコンパイル、署名、Archive、App Store Connectへの送信はmacOS側で行います。リモートMacを使う場合は、対話操作用のアカウントと自動ビルド用の実行アカウントを分け、同じFlutter SDK、Xcode、作業ディレクトリ、ロックファイルを使うようにします。

最低限、次の項目を固定してください。

  1. Flutter SDKの実体パスと選択バージョン。
  2. Xcodeの選択状態と利用するScheme。
  3. pubspec.lock、Package解決情報、Podfile.lock。
  4. 署名証明書と秘密鍵の保管場所。
  5. App Store Connect認証情報の注入方法。
  6. セッション切断後に再接続する手順と、途中生成物の扱い。

キャッシュは時間短縮のための補助であり、再現性の根拠ではありません。新しい作業ディレクトリ、またはキャッシュを使わない環境で依存を再解決し、同じ結果になるかを確認します。

専用のMacを準備する場合は、Mac miniのレンタルプランのように、利用期間と接続方法を先に確認しておくと、移行期間だけ本番環境を分離しやすくなります。接続やアカウント運用に不明点がある場合は、SSHMacのヘルプセンターで利用手順を確認してください。

ArchiveとTestFlightで正式切り替えを判定する

最後は、Debugの成功ではなく配布経路で判定します。Flutter公式のiOS公開手順では、Releaseビルド、Archive、IPAの書き出し、App Store Connectへの送信という段階を分けて確認します。FlutterのiOSビルドと公開手順に沿って、移行前後で同じSchemeと署名条件を使ってください。

確認順序は次のとおりです。

  1. Release設定でビルドし、ネイティブ機能を確認します。
  2. XcodeでArchiveを作成し、署名と埋め込みFrameworkを確認します。
  3. IPAを同じ配布方式で書き出します。
  4. App Store Connectへアップロードし、処理状態を確認します。
  5. TestFlightから実機へインストールし、通知、課金、カメラ、共有など対象プラグインを再確認します。
  6. 移行前チェーンで公開できるブランチを保持したまま、新チェーンの判定を行います。

Appleのビルドアップロード規則では、アップロード後にApp Store Connect側の処理を確認する必要があります。処理中、利用可能、失敗などの状態はそれぞれ意味が異なるため、アップロード直後に成功と判断しないでください。Appleのビルド状態一覧で状態を照合します。

切り替え条件は、SwiftPMへ完全移行することではありません。対象プラグインがすべて安定し、クリーン環境でArchiveとTestFlightの実機確認まで通った場合に完全移行します。未対応プラグインが残るならデュアルトラックを継続し、障害が解消しないなら旧経路へ戻して、次回の再確認条件を課題管理へ登録します。

Flutter 3.47 iOS依存関係の移行で迷ったときのFAQ

更新後にiOSプロジェクトが自動変更される理由

Flutter 3.44以降、iOSとmacOSのネイティブ依存関係でSwift Package Managerが標準経路になったためです。依存取得やXcode側の参照が変わる場合がありますが、変更を見つけた時点でCocoaPodsを削除する必要はありません。まず移行前のWorkspace、ロックファイル、成功済みArchiveと差分を比較してください。

SwiftPMに対応していないFlutterプラグインへの対処

未対応プラグインは、当面CocoaPodsで管理します。対応済みプラグインだけをSwiftPMへ移し、同じライブラリを二重に追加しないことが重要です。公式対応状況が不明な場合は、プラグインの設定ファイル、Podfileの独自処理、手動Frameworkを調べ、推測でソースコードを変更しないでください。

SwiftPMとCocoaPodsの併用条件

併用は可能ですが、ライブラリ単位で管理方式を分ける必要があります。重複シンボル、モジュール未検出、最小OSバージョンの衝突が出た場合は、まず同一依存関係が二つの経路から入っていないか確認します。解決結果をロックファイルと移行表へ記録し、Macごとの差異を残さないようにします。

Archive失敗時のロールバック

移行前のブランチと最後に成功したArchiveを残していれば、旧経路へ戻せます。新しい生成物を削除し、移行前のFlutter SDK、Xcode、ロックファイル、Podfileへ戻してから、無署名ビルド、Releaseビルド、Archiveの順に再確認します。署名証明書やApp Store Connect認証情報まで同時に変更しないことも重要です。

WindowsやLinuxからの移行確認

依存定義の確認やDartコードの開発はWindows、Linuxでも進められますが、XcodeによるiOSコンパイル、署名、Archive、TestFlight送信はmacOS側で実施します。リモートMacに固定したSDKとロックファイルを置き、クリーンな依存解決、Release、Archive、実機インストールまで同じ手順で検証してください。

現在の本番Macを守りながら移行する方法

本番用Macだけで移行すると、失敗時に公開作業そのものが止まります。WindowsやLinuxを中心に開発している場合も、iOS側の依存解決を確認するたびに同じMacへ接続しなければならず、途中でセッションが切れたときの復旧や証明書の扱いが負担になります。さらに、旧チェーンと新チェーンを同時に保つための作業領域も必要です。

そのため、Flutter 3.47の移行期間だけ独立したリモートMacを用意し、旧環境を温存したままSwiftPM、CocoaPods、Archive、TestFlightを比較する運用が現実的です。長期的に高負荷なビルドを常時回す場合や、物理的なiPhone接続が必須の場合は自社Macのほうが適していますが、短期の移行検証や公開前の隔離環境なら、SSHMacのMacレンタルを選択肢に入れる価値があります。

まずは新旧依存チェーンの両方をTestFlightで確認し、安定性と運用コストを見てから本番環境を切り替えてください。