結論
flutter build ipa の成果物に、objective_c.framework だけ古いビルドのまま混ざることがあります。
ストア提出用の ipa は、毎回 flutter clean してからビルドし、最後に otool で SDK を確認すると安全です。
(Flutter 3.41 / 2026年10月3日に遭遇した事例です)
事件 1:Transporter が 90086 で拒否
シミュレータで flutter run したあと、いつも通り ipa を作って Transporter にアップロードすると、こうなりました。
90086 / 90087 / 91169
調べると、objective_c.framework だけ x86_64(シミュレータ用) のままでした。
事件 2:Transporter は通るのに「無効なバイナリ」
Xcode 27 beta を試したあと、今度は Transporter を通過。ところが App Store Connect 側で、
このアプリは無効なバイナリ形式です
とだけ表示されて処理が止まります。
後からアカウントホルダー宛にメールが来ました。
ITMS-90512: Invalid sdk value - The value provided for the sdk portion of
LC_BUILD_VERSION in Runner.app/Frameworks/objective_c.framework/objective_c
is 27.2 which is greater than the maximum allowed value of 27.0
beta SDK(27.2)でビルドされた 1 本だけが紛れ込んでいたのです。
lipo や codesign はすべて正常に見えるので、ローカルでは気づけません。
原因
path_provider_foundation → objective_c の native assets は、.dart_tool 配下のキャッシュを使い回します。ところがこのキャッシュは ターゲットや SDK の変化を検知しません。
- hook の再ビルド自体は走る
- でも
build/native_assets/ios/objective_c.frameworkが更新されない - 結果、他の Pods は新しいのに、この 1 本だけ過去の状態になる
ちなみに build/native_assets/ios だけ消すのはダメでした。NativeAssetsManifest.json が参照切れになり、アーカイブが失敗します。
対策
1. ビルド前
xcode-select -p # beta でなく /Applications/Xcode.app か確認
flutter clean && flutter pub get
flutter build ipa
2. ビルド後に中身を確認
unzip -q build/ios/ipa/*.ipa -d /tmp/ipa
F=/tmp/ipa/Payload/Runner.app/Frameworks/objective_c.framework/objective_c
lipo -info "$F" # arm64 のみのはず
otool -l "$F" | grep -A3 LC_BUILD_VERSION # sdk が Runner と同じか
見るのは 2 点です。
- アーキテクチャが arm64 のみか
-
sdkが Runner 本体と同じで、beta でないか
まとめ
- ipa に 1 本だけ古い framework が混ざることがある
- 「無効なバイナリ」は、まず
objective_c.frameworkを疑う - 特に シミュレータで動かした後 と Xcode beta を使った後 は要注意
- ストア提出前は
flutter clean+otoolが保険になる
同じ沼にハマった人の時間を、少しでも節約できれば嬉しいです。