← All articles

Distribute your iOS code as an XCFramework

How to archive a framework for Apple platforms, combine its variants into an XCFramework and verify the binary before distribution.

Francesco Petrungaro

Principal Mobile Engineer · Bytes Cove

xcframework distribution

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.

Francesco Petrungaro

I help companies design, build and scale software products, from architecture and mobile engineering to AI in production.

What are you working on?

Tell me about the product, the team or the technical question you need help with. Pick the time that suits you.