Binary Frameworks in Swift — XCFrameworks

Anand Elumalai
Mac O’Clock
Published in
3 min readMay 1, 2020
Photo by Nick Fewings on Unsplash

Apple has introduced a new way of shipping Swift libraries in binary form from Xcode 11, known as Binary Frameworks. And XCFramework is a new supported way to distribute Binary frameworks.

What problem does it solve?

If we want to share a Swift library before Binary framework was introduced, we have to ship it with the source code due to Swift compiler compatibility error. Now, it is not required to share the source code with Binary frameworks.

XCFrameworks: It’s a single variant that can contain binaries for

  • Devices and Simulator
  • All platforms: iOS / MacOS / tvOS / watchOS
  • Mac apps using AppKit and UIKit

Previously, lipo command was used to build a fat library but it was never recommended officially by Apple.

Features of XCFrameworks

  1. It can bundle any of the following:
    - Frameworks,
    - Static libraries with headers (XCode will add header search path automatically)
    - Binary from Swift / C / Obj-C codes.
  2. It works on the future swift versions without any compiler issues.
  3. Entitlements and permissions available for the app are equally available for embedded XCFrameworks.

Obj-C Support

Binary frameworks can be embedded in Obj-C projects and used. It is supported by default.

The header files (listed below) required for Obj-C are generated by default.

framework.h: obj-c umbrella header.
framework-swift.h: generated header containing objc code for swift files.

If Swift classes in the framework do not have obj -c api, set “No” to “Install Obj c compatibility header” in Build Settings.

If Framework does not have obj-c api, set “No” to “Define Modules” in Build Settings.

Since Binary frameworks are dependent on module stability, and in turn, ABI stability, it needs Swift standard library in OS itself. Apple started including Swift standard library in OS when Xcode 10.2 was released, in which Swift 5 was supported. It means, iOS < 12.2 will not have a Swift standard library. So, in case of iOS version < 12.2, all swift apps will have their own runtime library included in it. In case of pure Obj-C projects, having embedded Binary frameworks, running in iOS < 12.2, ensure “Always Embed Swift Standard Libraries" to Yes in Build settings. Otherwise, it will crash in runtime.

How to Create XCFramework

We can create XCFramework in three simple steps.

  1. Create a Xcode Framework project and set “Yes” to “Build Libraries for Distribution” in Build Settings.
  2. Archive the project for required destinations. Here, i have done it for iOS Simulator and device alone.
    iOS Simulator: xcodebuild archive -scheme ShapeMaker -destination=”iOS Simulator” -archivePath “output/simulator.xcarchive” -sdk iphonesimulator SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
    iOS device: xcodebuild archive -scheme ShapeMaker -destination=”iOS” -archivePath “output/ios.xcarchive” -sdk iphoneos SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES
  3. Create XCFramework as shown below.
    xcodebuild -create-xcframework -framework “output/simulator.xcarchive/Products/Library/Frameworks/ShapeMaker.framework” -framework “output/ios.xcarchive/Products/Library/Frameworks/ShapeMaker.framework” -output “output/ShapeMaker.xcframework”

The above steps can be executed either in a single bash script or can create a Aggregate target in Xcode and run it in a separate Run Script phase.

XCFramework structure

It can be seen from the below snapshot that XCFramework contains Swift binaries for both iOS Simulator and device.

XCFramework sample structure

Thanks for reading! Hope you enjoyed this article.

If you’ve any questions or suggestions, please leave your response in the comments section.

Interested to connect, can reach me at LinkedIn. Tweet at @AnandFnc to say Hello.

--

--