Creating a Universal Framework in Xcode 9
This script will allow you to create a universal iOS framework that will run on a simulator and a mobile device, compatible with Xcode 9.
Join the DZone community and get the full member experience.
Join For FreeA while back, I posted a script for creating a universal iOS framework (i.e. one that will run in both the simulator as well as on an actual device) in Xcode 7. The following is an updated version for use with Xcode 9. This version should work with both Swift and Objective-C projects:
FRAMEWORK=<framework name>
BUILD=build
FRAMEWORK_PATH=$FRAMEWORK.framework
# iOS
rm -Rf $FRAMEWORK-iOS/$BUILD
rm -f $FRAMEWORK-iOS.framework.tar.gz
xcodebuild archive -project $FRAMEWORK-iOS/$FRAMEWORK-iOS.xcodeproj -scheme $FRAMEWORK -sdk iphoneos SYMROOT=$BUILD
xcodebuild build -project $FRAMEWORK-iOS/$FRAMEWORK-iOS.xcodeproj -target $FRAMEWORK -sdk iphonesimulator SYMROOT=$BUILD
cp -RL $FRAMEWORK-iOS/$BUILD/Release-iphoneos $FRAMEWORK-iOS/$BUILD/Release-universal
cp -RL $FRAMEWORK-iOS/$BUILD/Release-iphonesimulator/$FRAMEWORK_PATH/Modules/$FRAMEWORK.swiftmodule/* $FRAMEWORK-iOS/$BUILD/Release-universal/$FRAMEWORK_PATH/Modules/$FRAMEWORK.swiftmodule
lipo -create $FRAMEWORK-iOS/$BUILD/Release-iphoneos/$FRAMEWORK_PATH/$FRAMEWORK $FRAMEWORK-iOS/$BUILD/Release-iphonesimulator/$FRAMEWORK_PATH/$FRAMEWORK -output $FRAMEWORK-iOS/$BUILD/Release-universal/$FRAMEWORK_PATH/$FRAMEWORK
tar -czv -C $FRAMEWORK-iOS/$BUILD/Release-universal -f $FRAMEWORK-iOS.tar.gz $FRAMEWORK_PATH $FRAMEWORK_PATH.dSYM
When located in the same directory as the .xcodeproj file, this script will invoke xcodebuild twice on a framework project and join the resulting binaries together into a single universal binary. It will then package the framework up in a gzipped tarball and place it in the same directory.
However, apps that contain "fat" binaries like this don't pass app store validation. Before submitting an app containing a universal framework, the binaries need to be trimmed so that they include only iOS-native code. The following script can be used to do this:
FRAMEWORK=$1
echo "Trimming $FRAMEWORK..."
FRAMEWORK_EXECUTABLE_PATH="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}/$FRAMEWORK.framework/$FRAMEWORK"
EXTRACTED_ARCHS=()
for ARCH in $ARCHS
do
echo "Extracting $ARCH..."
lipo -extract "$ARCH" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$ARCH"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$ARCH")
done
echo "Merging binaries..."
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
echo "Done."
To use this script:
- Place the script in your project root directory and name it trim.sh or something similar.
- Create a new "Run Script" build phase after the "Embed Frameworks" phase.
- Rename the new build phase to "Trim Framework Executables" or similar (optional).
- Invoke the script for each framework you want to trim (e.g.
${SRCROOT}/trim.sh
).
For more ways to simplify iOS app development, please see my projects on GitHub:
Published at DZone with permission of Greg Brown, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments