DEV Community

Quang
Quang

Posted on

Building your own XCFramework

XCFramework is born to replace the traditional universal framework format .framework, which can contain both simulator and physical device architectures code. Besides, XCFramework can also support Catalyst, Mac, watchOS inside a framework

Using Apple provided tool

From Terminal, Using xcodebuild -create-xcframework which takes input -framework (from your previous archives) and -output

For example:

xcodebuild archive -workspace Alamofire.xcworkspace -scheme "Alamofire iOS" -sdk iphoneos13.0 OBJROOT=build/iOS xcodebuild archive -workspace Alamofire.xcworkspace -scheme "Alamofire iOS" -sdk iphonesimulator13.0 OBJROOT=build/simulator xcodebuild -create-xcframework -framework build/iOS/UninstalledProducts/iphoneos/Alamofire.framework -framework build/simulator/UninstalledProducts/iphonesimulator/Alamofire.framework -output build/Alamofire.xcframework 

Xcode build phase script

create new Aggregate target, add to New Run Script Phase. This new target should be in the same Xcode project with your framework target.

# Release dir path OUTPUT_DIR_PATH="${PROJECT_DIR}/XCFramework" function archivePathSimulator { local DIR=${OUTPUT_DIR_PATH}/archives/"${1}-SIMULATOR" echo "${DIR}" } function archivePathDevice { local DIR=${OUTPUT_DIR_PATH}/archives/"${1}-DEVICE" echo "${DIR}" } # Archive takes 3 params # # 1st == SCHEME # 2nd == destination # 3rd == archivePath function archive { echo "▸ Starts archiving the scheme: ${1} for destination: ${2};\n▸ Archive path: ${3}.xcarchive" xcodebuild clean archive \ -project "${PROJECT_NAME}.xcodeproj" \ -scheme ${1} \ -configuration ${CONFIGURATION} \ -destination "${2}" \ -archivePath "${3}" \ SKIP_INSTALL=NO \ OBJROOT="${OBJROOT}/DependentBuilds" \ BUILD_LIBRARY_FOR_DISTRIBUTION=YES | xcpretty } # Builds archive for iOS simulator & device function buildArchive { SCHEME=${1} archive $SCHEME "generic/platform=iOS Simulator" $(archivePathSimulator $SCHEME) archive $SCHEME "generic/platform=iOS" $(archivePathDevice $SCHEME) } # Creates xc framework function createXCFramework { FRAMEWORK_ARCHIVE_PATH_POSTFIX=".xcarchive/Products/Library/Frameworks" FRAMEWORK_SIMULATOR_DIR="$(archivePathSimulator $1)${FRAMEWORK_ARCHIVE_PATH_POSTFIX}" FRAMEWORK_DEVICE_DIR="$(archivePathDevice $1)${FRAMEWORK_ARCHIVE_PATH_POSTFIX}" xcodebuild -create-xcframework \ -framework ${FRAMEWORK_SIMULATOR_DIR}/${1}.framework \ -framework ${FRAMEWORK_DEVICE_DIR}/${1}.framework \ -output ${OUTPUT_DIR_PATH}/xcframeworks/${1}.xcframework } ### Static Libraries cant be turned into frameworks function createXCFrameworkForStaticLibrary { LIBRARY_ARCHIVE_PATH_POSTFIX=".xcarchive/Products/usr/local/lib" LIBRARY_SIMULATOR_DIR="$(archivePathSimulator $1)${LIBRARY_ARCHIVE_PATH_POSTFIX}" LIBRARY_DEVICE_DIR="$(archivePathDevice $1)${LIBRARY_ARCHIVE_PATH_POSTFIX}" xcodebuild -create-xcframework \ -library ${LIBRARY_SIMULATOR_DIR}/libStaticLibrary.a \ -library ${LIBRARY_DEVICE_DIR}/libStaticLibrary.a \ -output ${OUTPUT_DIR_PATH}/xcframeworks/${1}.xcframework } echo "#####################" echo "▸ Cleaning the dir: ${OUTPUT_DIR_PATH}" rm -rf $OUTPUT_DIR_PATH #### Dynamic Framework #### DYNAMIC_FRAMEWORK="${PROJECT_NAME}" echo "▸ Archive $DYNAMIC_FRAMEWORK" buildArchive ${DYNAMIC_FRAMEWORK} echo "▸ Create $DYNAMIC_FRAMEWORK.xcframework" createXCFramework ${DYNAMIC_FRAMEWORK} 

The above script build XCFramework for two architectures: generic/platform=iOS Simulator and generic/platform=iOS; saving to your project folder while assuming your framework scheme has the same name with project name.

Visit Gist

Using Carthage

While XCFramework is not fully supported, you can currently build XCFramework with this script:

carthage build --platform iOS --no-skip-current --create-xcframework 

Follow this issue request on Carthage GitHub for future updates

Top comments (0)