fix: enable Google ML Kit on Apple Silicon iOS 26+ simulators#862
Open
lucasdonordeste wants to merge 2 commits into
Open
fix: enable Google ML Kit on Apple Silicon iOS 26+ simulators#862lucasdonordeste wants to merge 2 commits into
lucasdonordeste wants to merge 2 commits into
Conversation
Apple removed Rosetta 2 from the default iOS 26 simulator runtime, which breaks `flutter run` for any project depending on Google ML Kit on Apple Silicon Macs. The published GoogleMLKit/* CocoaPods only ship arm64-iphoneos and x86_64-iphonesimulator slices and pin EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64, so the simulator build no longer finds a matching destination and dies with "Unable to find a destination matching the provided destination specifier". Until Google publishes proper arm64-iphonesimulator slices (https://issuetracker.google.com/issues/178965151), this change ships an opt-in Podfile helper under google_mlkit_commons that: 1. Re-labels the existing arm64 device slice of every ML Kit framework binary as iOS Simulator. Only the 4-byte LC_BUILD_VERSION.platform field is changed (2 -> 7), the same approach the well-known arm64-to-sim tool uses on closed-source SDKs. Idempotent. 2. Strips EXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64 from the xcconfigs CocoaPods generates from the pod's user_target_xcconfig, so the user's app target is allowed to build for arm64-iphonesimulator. The example/ios Podfile is wired to call the helper from post_install, which lets the example app build, install and run on an Apple Silicon iOS 26.3 simulator. End-to-end validated: Text Recognition on the Text-From-Widget view returned the exact widget text. Device builds and release builds are not affected. Closes flutter-ml#825
The Ruby and Python entry points already have a brief header pointing at the README. Per-function docstrings were restating what the function name already said, and the Podfile inline comments duplicated the helper's self-documenting name.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Fixes #825. Lets projects depending on
google_ml_kit_*build, install and run on iOS 26+ simulators on Apple Silicon Macs without Rosetta 2.Why this is needed
Google's
GoogleMLKit/*CocoaPods only ship two slices per framework:arm64-iphoneosandx86_64-iphonesimulator. Their podspecs propagateEXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64to the consuming app viauser_target_xcconfig. On Apple Silicon Macs running iOS 26+ simulators (where Rosetta 2 is not available by default), the simulator only runsarm64, soflutter runfails with:Root cause is upstream in Google's
MLKitCommon/MLImage/MLKit*binary distribution — it must includearm64-iphonesimulatorslices. Tracked at https://issuetracker.google.com/issues/178965151. Until that lands, every consumer of these plugins is locked out of iOS 26 simulators.What this PR does
Adds an opt-in Podfile helper under
google_mlkit_commons/ios/scripts/that runs atpod installtime:patch_arm64_simulator.py— walks everyMLKit*/MLImage*framework binary insidePods/, finds thearm64slice (a BSDarstatic archive of Mach-O 64 objects), and changes a single 4-byte field per object:LC_BUILD_VERSION.platform, from2(iOS) to7(iOS Simulator). Same approach as the well-knownarm64-to-simtool. Idempotent — re-runningpod installis a no-op once binaries already report platform=Simulator.apple_silicon_simulator.rb— Ruby helper exposingmlkit_apple_silicon_simulator_patch(installer)for use from any consumer'sPodfile. Also stripsEXCLUDED_ARCHS[sdk=iphonesimulator*] = arm64from the xcconfigs CocoaPods generates from each pod'suser_target_xcconfig.The example app's
Podfileis updated to call the helper frompost_install, andpackages/google_mlkit_commons/README.mddocuments the two lines a consumer needs to add to opt-in.Files touched:
packages/google_mlkit_commons/ios/scripts/patch_arm64_simulator.py(new)packages/google_mlkit_commons/ios/scripts/apple_silicon_simulator.rb(new)packages/google_mlkit_commons/README.md(docs section under iOS Requirements)packages/example/ios/Podfile(onerequire+ onemlkit_apple_silicon_simulator_patch(installer)call)packages/example/ios/Podfile.lock(auto-regen)Device builds, release builds, IPA builds — none of them are touched. The helper only runs when consumers add the two opt-in lines, and only modifies vendored binaries inside
Pods/plus pod-generated xcconfigs.Validation
End-to-end on this machine:
GoogleMLKit/*9.0.0,MLKitCommon14.0.0,MLImage1.0.0-beta8LC_BUILD_VERSIONand link as-is); 512 Mach-O objects relabeled totalSteps reproduced:
cd packages/example && flutter pub get && cd ios && pod install— patcher runs, prints[ml_kit] Patching 31 ML Kit framework(s) for Apple Silicon iOS Simulator...flutter run -d <iOS-26-sim-id>— Xcode build succeeds in ~38 s, no linker errors"This is sample text\nthat will be captured\nand processed using\nthe ML Kit Text Recognizer.\nTry different fonts\nand styles to test\nthe recognition capabilities!"), proving native MLKit inference runs correctly with the relabeled binaries.Runtime log noise observed: a
FaultforMLKITx_SRLRegistry: No binding was found for required, single-bound service: CCTPolicyVending_APIand anErrorforMLKITx_GIPPseudonymousIDStore: Shared App Groups unavailable— both are pre-existing Clearcut-telemetry / shared-storage warnings emitted by ML Kit in any debug build (sim or device); they do not block inference.Trade-offs and what's not validated
arm64-to-simapplies to other closed-source iOS SDKs. There is a non-zero risk that some MLKit code path expects an iOS-device-only system framework symbol that doesn't exist on the simulator. I only smoke-tested text recognition; barcode, face, pose, etc. weren't exercised. I'd appreciate maintainers' help validating other detectors before this is recommended for general use — that's why it's strictly opt-in and lives behind two Podfile lines.LC_BUILD_VERSION.platformfield in the load command isn't source-code extraction or algorithm analysis; Apple's ownvtoolships-set-build-versionfor exactly this purpose, andarm64-to-sim(582★) has done the same on closed Google SDKs for years without legal pushback. Maintainers may still want to make their own call here.google_mlkit_commonsversion or touch theCHANGELOG.md— happy to do either if preferred. Adding pure tooling underios/scripts/doesn't affect the published Dart/native runtime.exampleapp'sPRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)"is a pre-existing recursive value that breaksxcrun simctl install. To reproduce this PR's runtime smoke test you'll need to set a real bundle identifier locally first; the build itself succeeds either way. I deliberately left this out of the PR to keep scope narrow.How to reproduce on your machine
Test plan
google_mlkit_commonsversion