How do I create a binary XCFramework with SPM dependencies?

195 Views Asked by At

I'm trying to create a binary xcframework and I wanted it to have some SPM dependencies. Is it possible?

So far I'm facing the issue where I can't export my framework with a dependency because the BUILD_LIBRARY_FOR_DISTRIBUTION flag must be FALSE for the dependency to work. But in this case, I won't be able to generate the binary.

This is what I'm trying to do:

  1. Add a SPM as a dependency:

  2. Archive using xcodebuild:

    xcodebuild archive -project frameworkPOC.xcodeproj -scheme frameworkPOC -destination "generic/platform=iOS" -archivePath "archives/frameworkPOC"

  3. Generate binaries through:

    xcodebuild -create-xcframework -archive archives/frameworkPOC.xcarchive -framework frameworkPOC.framework -output xcframeworks/frameworkPOC.xcframework

So far so good... The exported framework works fine. But if I add a SPM such as Alamofire I get this warning:enter image description here

And when I export with BUILD_LIBRARY_FOR_DISTRIBUTION set to YES, the framework is broken as it seems Alamofire was not found.

So returning to my question: Is it possible to generate a binary framework that contains SPM dependencies?

1

There are 1 best solutions below

3
On BEST ANSWER

It is absolutely possible to create an xcframework that requires dependencies. You would publish a Package.swift that described the dependencies, and the app would link them all, along with your xcframework.

It is not advisable (or directly supported) to create an xcframework that includes dependencies.

Consider the case that another framework (xcframework or otherwise) also included Alamofire. At best, this would include a redundant copy. At worst, if the required versions are different, the program would have undefined behavior and which version is used would be determined at load time. This is a fundamental problem of including dependencies. It exists in just about every system, including xcframeworks. There is no safe way to hide the fact that you require Alamofire from the consumer of your framework. You need to include that in your Package.swift.

There are tricky ways to include dependencies directly if you can absolutely ensure that no consuming package, or dependency of the consuming package, also includes the dependency. That can in some cases be worth the trouble for managing purely internal packages. But this would never be the case for a broadly used framework like Alamofire.