App Store Connect にアプリをアップロードしたとき、こんなメッセージが出ました。
MinimumOSVersion too low. This app has a MinimumOSVersion of 13.0.
Starting in Spring 2027, all iOS apps must have a MinimumOSVersion of
15.0 or later in order to be uploaded to App Store Connect or submitted
for distribution. (90068)
2027年春から、iOSアプリは最低対応バージョンを15.0以上にしないとアップロードできなくなる、という予告です。
警告であって却下ではないので、そのときの審査はそのまま通りました。期限まで1年以上あります。でも「忘れないうちにやっておこう」と思って手をつけたら、これが思ったより手強かった、という話です。
その前に:誰か切り捨てることになるのか
最低バージョンを上げると聞くと、まず心配になるのが「古い端末の人が使えなくなるのでは」ということです。
調べてみたら、この心配は今回に限っては当てはまりませんでした。
iOS 13 と iOS 15 の対応端末は、まったく同じなんです。どちらも iPhone 6s / 6s Plus / SE(第1世代)以降、iPad は iPad Air 2 / iPad mini 4 以降。つまり 15.0 に上げても、切り捨てられるハードウェアはゼロ。いま iOS 13 や 14 のまま使っている方も、手持ちの端末そのままで、無料で iOS 15 に上げられます。
これが分かって、安心して作業に入れました。
1段目:Xcodeプロジェクトの数字を変える
まず素直に、Xcodeプロジェクトの設定を変えます。
ios/Runner.xcodeproj/project.pbxproj
IPHONEOS_DEPLOYMENT_TARGET = 13.0 → 15.0
Debug / Release / Profile の3構成すべてにあるので、3箇所です。
ついでに ios/Podfile の先頭を見たら、こうなっていました。
# Uncomment this line to define a global platform for your project
# platform :ios, '13.0'
コメントアウトされたまま。Flutterのテンプレートの初期状態です。ここも有効にしておきます。
platform :ios, '15.0'
これで終わり、のはずでした。
2段目:アーカイブが通らない
ビルドしたら、こうなりました。
Target Integrity (Xcode): The iOS deployment target 'IPHONEOS_DEPLOYMENT_TARGET'
is set to 13.0, but the range of supported deployment target versions is 15.0 to 27.0.x.
ios/Pods/Pods.xcodeproj
同じようなエラーが12個。全部 Pods.xcodeproj、つまりプラグイン側です。
「15.0にしたはずなのに、13.0って言われている」。ここで少し混乱しました。
Pods.xcodeproj の中身を数えてみたら、こうでした。
(Podsプロジェクト自体) 13.0
flutter_native_splash_privacy 9.0 ← いちばん古い
in_app_purchase_storekit 13.0
in_app_review_privacy 12.0
package_info_plus_privacy 12.0
path_provider_foundation 13.0
shared_preferences_foundation 13.0
url_launcher_ios 13.0
…
合計36構成が 15.0 未満
Podfile の platform :ios, '15.0' が効くのは、自分のアプリ本体だけだったんです。
個々のプラグインの最低対応バージョンは、Flutterが用意している flutter_additional_ios_build_settings という関数が決めています。そしてこの関数は、各Podを Flutter本体の下限である 13.0 にそろえます。
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target) # ← ここで13.0にされる
end
end
Flutterとしては何も間違っていません。「Flutterが動く下限は13.0だから、そこにそろえておくね」という、まっとうな処理です。
なぜ今まで通っていたのか
ここが今回いちばん腑に落ちた点でした。
この13.0は昔からずっと13.0でした。 前回までのビルドでもそうだったはずです。では、なぜ今回だけ止まったのか。
エラーメッセージをもう一度見てください。
the range of supported deployment target versions is 15.0 to 27.0.x
Xcodeがサポートする下限が、15.0に上がっていたんです。
つまりこれは「私が上げ忘れていた」話ではなく、Xcode側が古い指定を受け付けなくなった話でした。Appleが2027年春に向けて締め付けを始めていて、開発ツール側が先に動いていた、ということになります。
紙吹雪が舞わなかったときと同じで、原因は自分のコードに一行も書かれていませんでした。
3段目:post_install で上書きする
対処は、Flutterの設定を当てたあとに自分で上書きすることです。
post_install do |installer|
# Podsプロジェクト自体の構成
installer.pods_project.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
end
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
# ↑ が13.0にそろえてしまうので、そのあとに15.0で上書きする
target.build_configurations.each do |config|
config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.0'
end
end
end
順番が大事です。flutter_additional_ios_build_settings の前に書いても、あとから13.0に戻されて意味がありません。
pod install をやり直して数え直したら、57構成すべてが15.0になりました。15.0未満はゼロ。実機でも無事に動きました。
おまけ:従ってはいけない警告
作業中、こんな警告も出ました。
[!] CocoaPods did not set the base configuration of your project because
your project already has a custom config set. In order for CocoaPods
integration to work at all, please either set the base configurations of
the target `Runner` to `Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig`
...
親切に対処法まで書いてくれています。でもこれに従うと壊れます。
Flutterプロジェクトでは Flutter/Release.xcconfig がこうなっています。
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
2行目の Generated.xcconfig には FLUTTER_ROOT などが入っていて、Flutterのビルドスクリプトがこれを読みます。警告の言うとおりに base configuration をPodsのものに差し替えると、この行ごと外れてしまい、xcode_backend.sh failed with a nonzero exit code でビルドが通らなくなります。
Flutter側もこの件を把握していて、「メッセージが誤解を招くのが問題」としてissueを閉じています。
ちなみにこの警告が出る理由は、Runnerの Profile構成 が Release.xcconfig を共用していて、Pods-Runner.profile.xcconfig を読んでいないからです。Profile構成は flutter run --profile(パフォーマンス計測)でしか使わないので、App Storeに出すRelease ビルドには影響しません。無視していい警告でした。
今回の学び
1. 設定は「どこに効くか」を確認する
Podfile に platform :ios, '15.0' と書けば全部に効く、と思い込んでいました。実際に効いたのはアプリ本体だけ。書いた場所と、効く範囲は別です。
2. 数えると早い
「たぶんPodsのどれかが古い」と当たりをつけて探すより、Pods.xcodeproj を機械的に数えて「36構成が15.0未満」と分かったほうが、圧倒的に早く進みました。直したあとも「57構成すべて15.0、未満はゼロ」と数え直して確認できます。
3. エラーメッセージは「自分が間違えた」とは限らない
今回の直接の引き金は、Xcode側のサポート下限が上がったことでした。「13.0のままだった」のは前からで、それが急に問題になった。変わったのは自分ではなく環境のほう、というパターンがあります。
4. 親切な自動化ほど、上書きのタイミングが要る
flutter_additional_ios_build_settings は良い仕事をしています。ただ「Flutterの下限」と「Xcodeの下限」と「自分のアプリの下限」が食い違うと、誰も悪くないのに詰まる。こういうときは、順番を意識して最後に自分の意思を書くしかありません。
「数字を1つ変えるだけ」と思っていた作業が、結局3段構えになりました。でも次に同じことをやるときには10分で終わります。詰まったこと自体より、詰まった理由を記録しておくことのほうが大事なのかもしれません。
