
Build a Universal XCFramework with a Single Script
Introduction:
XCFrameworks are Apple’s preferred way to distribute binary frameworks, supporting multiple platforms and architectures within a single package. This article walks you through automating the creation of a universal XCFramework using a handy Bash script.
Prerequisites:
- Xcode command-line tools installed
- A working Xcode project with a framework target
Steps:
- Get the Script: Copy the provided Bash script into a file (e.g.,
build_xcframework.sh
) and save it in your project's root directory. - Customize:
- Open
build_xcframework.sh
in a text editor. - Replace
"YourProjectName"
with your actual Xcode project name (without the.xcodeproj
extension). - Replace
"YourSchemeName"
with your framework's scheme name. - (Optional) Change the
OUTPUT_FOLDER
variable to your preferred output location.
- Run the Script:
- Open your terminal and navigate to your project’s root directory.
- Make the script executable:
chmod +x build_xcframework.sh
- Execute the script:
./build_xcframework.sh
- Check for Success:
- The script will clean, build, archive, and create the XCFramework.
- Find your XCFramework in the specified output folder (e.g.,
output/<YourSchemeName>.xcframework
).
Explanation:
- The script first cleans the build directory to start fresh.
- It then builds your project for both iOS and iOS Simulator destinations, creating separate archives.
- Finally, it combines the archives into a universal XCFramework containing both architectures.
Integrating with Xcode (Optional):
- In Xcode, go to your target’s “Build Phases” tab.
- Click “+” to add a “New Run Script Phase.”
- Paste the Bash script into the script area.
- Drag the new run script phase above “Copy Bundle Resources” for proper execution order.
- Now, building your project will automatically create the XCFramework.
Key Points:
- This script assumes a single framework target. Adapt it if you have multiple frameworks.
- Add error checks to the script for better robustness.
- Explore the
xcodebuild
command's options to further customize your build process.
Let me know if you’d like help adapting this for multiple architectures or integrating it as a build phase script in Xcode by commenting.
#!/bin/bash
# --- Configuration ---
PROJECT_NAME="YourProjectName" # Replace with your Xcode project name
SCHEME_NAME="YourSchemeName" # Replace with your scheme name
OUTPUT_FOLDER="output" # Choose your desired output folder
# --- Derived Variables ---
BUILD_FOLDER="build"
ARCHIVE_PATH_IOS="$BUILD_FOLDER/$SCHEME_NAME-iOS"
ARCHIVE_PATH_SIMULATOR="$BUILD_FOLDER/$SCHEME_NAME-iOS_Simulator"
FRAMEWORK_NAME="$SCHEME_NAME.framework"
XCFRAMEWORK_NAME="$SCHEME_NAME.xcframework"
XCFRAMEWORK_PATH="$OUTPUT_FOLDER/$XCFRAMEWORK_NAME"
# --- Script ---
rm -rf "$BUILD_FOLDER" "$OUTPUT_FOLDER"
xcodebuild clean -project "$PROJECT_NAME.xcodeproj" -scheme "$SCHEME_NAME"
xcodebuild archive \
-project "$PROJECT_NAME.xcodeproj" \
-scheme "$SCHEME_NAME" \
-configuration Release \
-destination "generic/platform=iOS" \
-archivePath "$ARCHIVE_PATH_IOS" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive \
-project "$PROJECT_NAME.xcodeproj" \
-scheme "$SCHEME_NAME" \
-configuration Release \
-destination "generic/platform=iOS Simulator" \
-archivePath "$ARCHIVE_PATH_SIMULATOR" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild -create-xcframework \
-framework "$ARCHIVE_PATH_IOS.xcarchive/Products/Library/Frameworks/$FRAMEWORK_NAME" \
-framework "$ARCHIVE_PATH_SIMULATOR.xcarchive/Products/Library/Frameworks/$FRAMEWORK_NAME" \
-output "$XCFRAMEWORK_PATH"
Enjoyed this article? Did you find it helpful? Support me here