From ac294874bf744a1c8f422e569b37453d8491cfe0 Mon Sep 17 00:00:00 2001 From: jwinterm Date: Tue, 2 Jun 2026 13:39:30 -0400 Subject: [PATCH] iOS TestFlight: patch LibTorch Info.plist to match binary LC_BUILD_VERSION MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LibTorch.xcframework ships with each slice's Info.plist claiming MinimumOSVersion=12.0, but the Mach-O LC_BUILD_VERSION inside the binaries actually requires 13.0 (device) and 14.0 (simulator). Apple's validator catches the lie and rejects TestFlight uploads with ITMS-90208 ("LibTorch.framework does not support the minimum OS Version specified in the Info.plist") regardless of the app's deployment target. Revert the previous 15.0 deployment-target bump (which was based on the wrong hypothesis) back to 13.0 — that's actually what LibTorch supports. Add a workflow step that plutil-rewrites both slice Info.plists to match the value their binary actually requires. Bump build number 1.0.0+2 -> 1.0.0+3 for the re-upload. --- .github/workflows/build-ios-testflight.yml | 28 +++++++++++++++------- ios/Flutter/AppFrameworkInfo.plist | 2 +- ios/Podfile | 2 +- ios/Runner.xcodeproj/project.pbxproj | 12 +++++----- pubspec_description.yaml | 2 +- 5 files changed, 28 insertions(+), 18 deletions(-) diff --git a/.github/workflows/build-ios-testflight.yml b/.github/workflows/build-ios-testflight.yml index 9833e99d0..48a2a1131 100644 --- a/.github/workflows/build-ios-testflight.yml +++ b/.github/workflows/build-ios-testflight.yml @@ -144,15 +144,25 @@ jobs: tar -xzf torch_dart.tar.gz -C torch_dart rm torch_dart.tar.gz popd - # Diagnostic: print LibTorch.xcframework's required min iOS so we - # know whether the app's IPHONEOS_DEPLOYMENT_TARGET in pbxproj is - # high enough. Apple's TestFlight ITMS-90208 fires when the app - # claims to support an older iOS than this framework does. - LIBTORCH_PLIST=$(find scripts/torch_dart -path '*LibTorch.xcframework/*' -name Info.plist 2>/dev/null | head -1) - if [[ -n "$LIBTORCH_PLIST" ]]; then - echo "LibTorch xcframework Info.plist: $LIBTORCH_PLIST" - plutil -p "$LIBTORCH_PLIST" 2>/dev/null | grep -E "MinimumOSVersion|SupportedPlatform|SupportedArchitectures" || true - fi + # LibTorch.xcframework ships with a lie: each slice's Info.plist + # claims MinimumOSVersion=12.0, but the Mach-O LC_BUILD_VERSION + # in the binaries says 13.0 (device) and 14.0 (simulator). + # Apple's TestFlight validator catches this mismatch and rejects + # the upload with ITMS-90208. Patch the Info.plists to match + # the actual binary build versions. + DEVICE_PLIST=scripts/torch_dart/ios/LibTorch.xcframework/ios-arm64/LibTorch.framework/Info.plist + SIM_PLIST=scripts/torch_dart/ios/LibTorch.xcframework/ios-arm64-simulator/LibTorch.framework/Info.plist + for entry in "$DEVICE_PLIST:13.0" "$SIM_PLIST:14.0"; do + plist="${entry%:*}" + min="${entry#*:}" + if [[ -f "$plist" ]]; then + plutil -replace MinimumOSVersion -string "$min" "$plist" + echo "patched $plist -> MinimumOSVersion $min" + plutil -p "$plist" | grep -E "MinimumOSVersion|CFBundleName" || true + else + echo "WARNING: $plist not found" + fi + done - name: Fetch prebuilt reown_flutter run: | diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist index 7b1095736..c5ff5d37e 100644 --- a/ios/Flutter/AppFrameworkInfo.plist +++ b/ios/Flutter/AppFrameworkInfo.plist @@ -21,6 +21,6 @@ CFBundleVersion 1.0 MinimumOSVersion - 15.0 + 13.0 diff --git a/ios/Podfile b/ios/Podfile index d98512585..cf24cb605 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -1,5 +1,5 @@ # Uncomment this line to define a global platform for your project -platform :ios, '15.0' +platform :ios, '13.0' source 'https://github.com/CocoaPods/Specs.git' # CocoaPods analytics sends network stats synchronously affecting flutter build latency. diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a96351c68..43273e5e4 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -469,7 +469,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -499,7 +499,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -568,7 +568,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -618,7 +618,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -650,7 +650,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -694,7 +694,7 @@ "$(PROJECT_DIR)", ); INFOPLIST_FILE = Runner/Info.plist; - IPHONEOS_DEPLOYMENT_TARGET = 15.0; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", diff --git a/pubspec_description.yaml b/pubspec_description.yaml index 24757ad5f..b3f6ded0f 100644 --- a/pubspec_description.yaml +++ b/pubspec_description.yaml @@ -1,6 +1,6 @@ name: hash_wallet description: Hash Bags — a noncustodial multi-currency wallet by Such Software LLC. -version: 1.0.0+2 +version: 1.0.0+3 publish_to: none environment: