With Xcode 11, the ipa’s export process now can result in an error if you try to export an app that contains fat binaries. Until now, we would found this error only when we were trying to send it to App Store, but Xcode now seems to be trying to give us a “little help”.
If you tried to do that in Xcode 11, you may had faced an error like this:

Checking logs, we found out some precious, but not very clear, information:
2020-03-22 22:14:41 +0000 /Applications/Xcode.app/Contents/Developer/usr/bin/ipatool exited with 1
2020-03-22 22:14:41 +0000 ipatool JSON: {
alerts = (
{
code = 3620;
description = "Configuration issue: platform AppleTVSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
info = {
};
level = WARN;
},
{
code = 3620;
description = "Configuration issue: platform WatchSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
info = {
};
level = WARN;
},
{
code = 3620;
description = "Configuration issue: platform iPhoneSimulator.platform doesn't have any non-simulator SDKs; ignoring it";
info = {
};
level = WARN;
}
);
}
The fat binary problem
We have some problems here. In addition to Apple’s rejection of the binary, exporting an app with fat binaries ends up considerably increasing the size of your exported ipa. See the example below:
Fat binaries

Striped archs:

We can clearly see that the ipa with fat binaries increases the size of the exported file by 96% in a simple example, with only one embedded Framework.
Removing the simulator architectures will reduce the size of our ipa and cause Apple to accept uploading our app.
Removing simulator architectures while building your app
In the Build Phase of your main app, add a new run script phase and paste the code below:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and
# removes unused architectures.
# If some frameword doesn't have an invalid architecture, the script does
# nothing to it and just goes to the next one
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep -v --silent "i386\|x86_64"; then
echo "This framework does not contain simulator archs: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
Based on Daniel Kennett’s original script, available in: https://medium.com/@maximbilan/ios-submission-unsupported-architectures-issues-733917a98cc3
Categories: Tutorials
