Xcode 12.3: Building for iOS Simulator, but the linked and embedded framework was built for iOS + iOS Simulator
I'm afraid that this is actually the correct error and the framework shouldn't contain iOS and iOS Simulator code at the same time. Apple tries to force us to use
XCFrameworks for this purpose. They started it in XCode 11 and just tightened up the restrictions.
The only correct way to resolve this is to rebuild the framework as an XCFramework. Which is easy to do:
$ xcrun xcodebuild -create-xcframework \ -framework /path/to/ios.framework \ -framework /path/to/sim.framework \ -output combined.xcframework
You can start with a combined
.framework make two copies of the framework, and use
lipo to remove the slices from the binary that are associated with a different SDK.
Based on the original answer from Apple here.
My particular case is that I'm getting this error using Rome, which produces these frameworks (a possible solution is here). Also, a lot of struggling is going on on the Carthage side.
Hope that helps ;)
You have to exclude device architectures while building for simulator and while building for the device you have to exclude simulator's architectures.
To do that, navigate to
Build Settings of your project ->
Excluded Architectures -> Select the configuration(Debug/Release/Etc...) -> Tap + ->
Any iOS Simulator SDK -> Add
Any iOS SDK.
PS: You can check all the architectures which are present in your framework by running
file <path_to_framework_binary> or
lipo -info <path_to_framework_binary>.
I have a framework with universal binary that contains
arm64 which I merge with
lipo with a custom script at framework build time. I encountered this same issue for XCode 12.3 and have created a work around for now. Hopefully this will get fix in XCode quickly, but until then, one quick fix would be to thin the architectures and use the framework that you need. EDIT: please see my answer here on how to start producing .xcframeworks which is the long term solution for framework authors
For instance, let's assume I'm in a terminal in the working directory where my universal framework
some_framework.framework is. If I want to run on an actual physical device, I execute the following command:
lipo -thin arm64 some_framework.framework/some_framework -output some_framework
With the above command, you extract the
arm64 binary. Afterwards, replace the current
some_framework.framework/some_framework with the newly generated
arm64 only binary
mv some_framework some_framework.framework
If you have a universal framework built only from Objective-C sources, your job is done. But if you've got swift code too, then you would need to update
some_framework.framework/Modules/some_framework.swiftmodule so that it does not contain any references to architectures that are not
You would follow a similar process for running on the simulator except that you need
x86_64. I'm currently now maintaining two versions of my framework until this is fixed. Whenever I switch between the simulator and the device, I simply switch out which framework is in my project.