Distribute your code as XCFramework

General, iOS, Xcode

To distribute code in binary form I suggest to create an XCFramework artifact that contains the binaries.
This will allow you to make your code available as binary to protect your intellectual property.

Since Xcode 11 XCFramework simultaneously support distribution to devices, simulators and MacOS in one single bundle. On top of that, since swift 5.3, it is possibile to distribute the XCFramework in binary form as Swift Package. To achieve this I recommend using Xcode 12.2 and above (previous versions of Xcode have a bug that it has been fixed in the version mentioned above).

Let’s build the XCFramework

This section contains the steps to create an xcframework from a devices build and simulators build. Obviously this can be applied also to MacOS.
In order to create the XCFramework for your ExampleFramework follow the steps below

Coming from Swift Framework

1. Build the framework for the devices with following command:

xcodebuild archive \
-scheme ExampleFramework \
-sdk iphoneos \
-archivePath "result/devices.xcarchive" \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
SKIP_INSTALL=NO

2. Build the framework for simulators with the following command:

xcodebuild archive \
-scheme ExampleFramework \
-sdk iphonesimulator \
-archivePath "result/simulators.xcarchive" \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES \
SKIP_INSTALL=NO

3. Build the XCFramework with the following command:

Let’s extract all these frameworks from the archives and pack them together in a XCFramework

xcodebuild -create-xcframework \
-framework archives/devices.xcarchive/Products/Library/Frameworks/ExampleFramework.framework \
-framework archives/simulators.xcarchive/Products/Library/Frameworks/ExampleFramework.framework \
-output result/ExampleFramework.xcframework

And now ExampleFramework.xcframework will be under the result folder.

Coming from Static Library

1. Build the framework for the devices with following command:

xcodebuild build \
-scheme ExampleLibrary \
-derivedDataPath derived_data \
-arch arm64 \
-sdk iphoneos \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
mkdir -p result/devices
cp -r derived_data/Build/Products/Debug-iphoneos/ result/devices

2. Build the framework for simulators with the following command:

xcodebuild build \
-scheme ExampleLibrary \
-derivedDataPath derived_data \
-arch x86_64 \
-sdk iphonesimulator \
BUILD_LIBRARY_FOR_DISTRIBUTION=YES
mkdir -p result/simulators
cp -r derived_data/Build/Products/Debug-iphonesimulator/ result/simulators

3. Build the XCFramework with the following command:

Let’s pack together all libraries in one single XCFramework

xcodebuild -create-xcframework \
-library result/simulators/libExampleLibrary.a \
-library result/devices/libExampleLibrary.a \
-output result/ExampleFramework.xcframework

And now ExampleFramework.xcframework will be under the result folder.

xcodebuild params

Set BUILD_LIBRARY_FOR_DISTRIBUTION=YES to make sure future binary compatibility will be guaranteed.

Set SKIP_INSTALL=NO to install the framework in the archive.

How to use ExampleFramework.xcframework

Drag and drop

Drag and drop ExampleFramework.xcframework into the project navigator pane as you would do with any other file but make sure that the framework gets embedded properly into the app when the app gets built

  1. Select project settings
  2. Select the app target
  3. Select General tab
  4. Scroll to “Frameworks, Libraries, and Embedded Content”
  5. Make sure that ExampleFramework.xcframework “Embed” option set to “Embed & Sign”

Swift Package Manager

Once you have built the XCFramework the you have to zip it into single file.

I suggest you to renamed to include the version number and then host it remotely somewhere so that other devs can reach it.

Create a Swift Package project for it directly from Xcode. More info on this page: https://developer.apple.com/documentation/swift_packages/distributing_binary_frameworks_as_swift_packages