An XCFramework packages multiple variants of a library in one distributable bundle. Each variant targets a specific platform and architecture combination, such as iOS devices or the iOS Simulator. This is the preferred format when you need to distribute compiled code across Apple platforms.
Prepare the framework target
Start with a framework target that exposes only the API your clients need. Set BUILD_LIBRARY_FOR_DISTRIBUTION=YES when creating archives for binary distribution. For Swift frameworks, this generates module interfaces that help preserve compatibility across supported compiler versions.
Archive each platform variant
xcodebuild archive \
-scheme MyFramework \
-destination "generic/platform=iOS" \
-archivePath "build/MyFramework-iOS" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
xcodebuild archive \
-scheme MyFramework \
-destination "generic/platform=iOS Simulator" \
-archivePath "build/MyFramework-Simulator" \
SKIP_INSTALL=NO \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
Use a generic destination for every platform variant you support. The resulting archives keep binaries, module metadata and debug symbols together. If the framework produces dSYMs or BCSymbolMaps, include the corresponding files when creating the XCFramework.
Create the XCFramework
xcodebuild -create-xcframework \
-archive "build/MyFramework-iOS.xcarchive" \
-framework MyFramework.framework \
-archive "build/MyFramework-Simulator.xcarchive" \
-framework MyFramework.framework \
-output "build/MyFramework.xcframework"
Using -archive keeps the framework and its associated symbols tied to the same archive. You can also use -framework with direct paths, but you then need to pass each debug-symbol path yourself.
Verify the result
- Add the XCFramework to a clean sample application.
- Build and run on a physical device and the Simulator.
- Archive the sample app to catch distribution-only failures.
- Check that symbolication works with the distributed dSYMs.
- Confirm that no private headers or internal resources are exposed.
If you distribute the binary through Swift Package Manager, host a stable ZIP archive, calculate its checksum with swift package compute-checksum and reference the URL and checksum from a binary target. Keep the URL immutable for each released version.
Apple’s current command options and examples are available in the XCFramework documentation.




