How to use Swift Package Manager's binaryTarget?

Viewed 3768
2 Answers

First of all, your example is not testable because you have forgotten to provide a version tag, so this is not a real package.

Second, and more important, I think you have a misconception about how a package works as a binary target. You seem to think that your Swift Package can contain code that sees the XCFramework. (That's why you are trying to import in the framework module in the Sources code of the package.) That's wrong. It's the app that imports the framework module. The package is merely a way of distributing the framework.

In other words, you can write a source code package or a framework-bearing package. One package cannot be both.

But of course you can write a source code package that depends on a framework-bearing package.

First, you don't need a version tag for it to be "real package". You can specify package dependencies via commit SHA and branch as well. Also you can add local package repos in xcode via file://. Note, this is NOT the same as a local dev override.

I didn't have much luck with swift build but I did get it to work fine by creating an app in Xcode and adding the package to it. I think this is what @matt is getting at. You need to import it into a project (xcode, or another SP) and then xcode will assemble all the dependencies when it ~~builds~~ feels like it.

Here's the modified Package.swift I used. I changed the name to Example (as that's presumably the SDK you are building which depends on Stripe). You can include "Stripe" in the Example library's targets if you want it embedded in its framework. Otherwise the client app just needs to import it as well (via the tickboxes when you add it in Xcode, or via dependencies in another Package.swift).

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "Example",
    platforms: [
        .iOS(.v11)
    ],
    products: [
        .library(
          name: "Example",
          type: .dynamic,
          targets: ["Example"]),
        .library(
            name: "Stripe",
            targets: ["Stripe"])
    ],
    dependencies: [],
    targets: [
        // I thought this was defining the Stripe binaryTarget...
        .binaryTarget(name: "Stripe",
                      url: "https://github.com/stripe/stripe-ios/releases/download/v19.3.0/Stripe.xcframework.zip",
                      checksum: "fe459dd443beee5140018388fd6933e09b8787d5b473ec9c2234d75ff0d968bd"),
        // ... and then linking it to the Example project here via "dependencies" ...
        .target(name: "Example", dependencies: ["Stripe"], path: "Sources")
        // ... so when I'm in "Example" files, I thought I'd be able to import "Stripe" to them
    ]
)
Related