17

I'm developing a closed source framework that will be distributed as an XCFramework using SPM. This is possible thanks to the new binaryTarget(name:path:) and binaryTarget(name:url:checksum:) methods available in swift tools 5.3. This works fine until the framework has dependencies.

The Binary Frameworks in Swift talk from WWDC 2019 states that "binary frameworks cannot depend on packages" but this was before 5.3 and binary targets were not possible at all. On the Swift forums there is a suggested workaround that basically revolves around adding a dummy target that will list the dependencies (the binaryTarget(...) methods don't have a dependencies parameter).

The workaround works until the dependency has its own dependencies. For example Lottie which doesn't have any dependencies works fine, but Auth0 which has quite a few, fails with errors Missing required modules: 'Auth0ObjectiveC', 'SimpleKeychain'. Even adding Auth0 directly to the client project using SPM doesn't fix these errors.

Here is my Package.swift which works partially.

// swift-tools-version:5.3
import PackageDescription
let package = Package(
    name: "MyFramework",
    platforms: [
        .iOS(.v13)
    ],
    products: [
        .library(name: "MyFramework", targets: ["MyFramework", "MyFramework-Dependencies"])
    ],
    dependencies: [
        .package(name: "Auth0", url: "https://github.com/auth0/Auth0.swift.git", from: "1.30.1")
    ],
    targets: [
        .binaryTarget(name: "MyFramework", path: "MyFramework.xcframework"),
        .target(name: "MyFramework-Dependencies", dependencies: ["Auth0"], path: "MyFramework-Dependencies")
    ])

It it possible to actually have a binary framework depend on a package? If not, what would be the proper way distribute a dependency for a binary framework?

2
  • Did you find an adequate solution to this problem? I am wondering the same. Commented Jun 9, 2021 at 19:01
  • 1
    @IgorGanapolsky we've extracted the part that relies on these dependencies into a separate standard SPM package, and then request 3rd party developers to inject it into the main framework. Commented Jun 10, 2021 at 10:15

1 Answer 1

9

We've solved this problem by creating a wrapper target that depends on both the binary framework and other dependencies. See an example here.

Sign up to request clarification or add additional context in comments.

2 Comments

Sorry for the late response, holidays and vacation. Based on what you posted I've updated Package.swift so that MyFramework has a MyFrameworkTarget target which depends on MyFrameworkWrapper, which depends on Auth0 and MyFrameworkBinary. Importing MyFrameworkTarget doesn't throw any errors, but it doesn't expose anything from MyFrameworkBinary. The same goes if I try to import MyFrameworkWrapper. Importing MyFrameworkBinary throws the same error I posted in the question. Is there a step I'm missing?
I had face same kind of issue and followed this approach. But still I am getting a build error due to unable to link sub dependency. If someone has an idea why please have a look on my detailed question. stackoverflow.com/questions/71824920/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.