Removing Unsupported Architectures [x86_64, i386] in Xcode/iOS IPA/Archive
XCODE/IOS Remove Unsupported Architecture [x86_64, i386] in IPA / Archive
TARGET -> BUILD PHASES -> RUN SCRIPT
🎯 Issue Overview
When building an iOS application in Xcode, you may encounter issues related to unsupported architectures, such as x86_64 and i386, which are typically used for Mac or simulator builds. These architectures should be removed from the final IPA (iOS application package) or archive to ensure compatibility and reduce the app size. In this article, we will explore a script that can be added to the build phases in Xcode to automate the removal of these unsupported architectures.
🎯 For Older Swift Versions
For older versions of Swift (pre-Swift 4), you can use the following script in the Xcode build phases:
Source code
bash
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
# This script loops through the frameworks embedded in the application and removes unused architectures.
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"
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
Explanation:
The APP_PATH variable represents the path to the application within the build directory.
The script uses the find command to locate the frameworks embedded in the application.
For each framework found, it retrieves the executable name from the Info.plist file.
The script then iterates over the desired architectures ($ARCHS) and extracts each architecture using the lipo command.
The extracted architectures are stored in the EXTRACTED_ARCHS array.
After extracting all desired architectures, the script merges them back together using lipo and replaces the original framework executable with the thinned version.
🎯 For Swift 4 and 5:
For Swift 4 and 5, the following script can be used:
Source code
bash
APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
FRAMEWORK_NAME="Your_Framework_Name.framework"
# Check if the framework is present.
FRAMEWORK_LOCATION=$(find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d)
if [ -z $FRAMEWORK_LOCATION ]; then
echo "Couldn't find Your_Framework_Name.framework in $APP_PATH. Make sure 'Embed Frameworks' build phase is listed before the 'Strip Unused Architectures' build phase."
exit 1
fi
# This script strips unused architectures.
find "$APP_PATH" -name "$FRAMEWORK_NAME" -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"
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
Explanation:
The APP_PATH variable represents the path to the application within the build directory.
The FRAMEWORK_NAME variable should be replaced with the actual name of your framework.
The script checks if the framework is present in the application bundle and exits if it is not found.
Similar to the previous script, it iterates over the desired architectures and performs the extraction and merging process using lipo.
Finally, the original executable is replaced with the thinned version by removing the old file and renaming the merged one.
By adding these scripts to the Xcode build phases, you can ensure that unsupported architectures such as x86_64 and i386 are removed from the final IPA or archive. This not only improves compatibility but also reduces the app's size, resulting in a more optimized release.
Feel free to customize the scripts according to your specific project requirements and framework names. Remember to add these scripts as a build phase before the "Embed Frameworks" build phase.