Consume Swift Package for multiple targets and platforms in a project?

SwiftXcode11Swift Package-Manager

Swift Problem Overview


I have a project with multiple targets, such as an iOS app, a watchOS app, and some frameworks. How can I assign the same Swift Package to all my targets? Xcode only let's me select one:

SPM1

If I try to add the Swift Package again so I can try assigning it to another target in my project, I get an error:

SPM2

What is the correct way to do this? Below is what the package manifest looks like in the Swift Package. Is there something to be done on that side or something I have to do different in Xcode?

import PackageDescription

let package = Package(
    name: "Alamofire",
    platforms: [
        .macOS(.v10_12),
        .iOS(.v10),
        .tvOS(.v10),
        .watchOS(.v3)
    ],
    products: [
        .library(
            name: "Alamofire",
            targets: ["Alamofire"])
    ],
    targets: [
        .target(
            name: "Alamofire",
            path: "Source")
    ],
    swiftLanguageVersions: [.v5]
)

Swift Solutions


Solution 1 - Swift

I had the same problem, and I only found this two solutions:

First, add the package to the first target:

Add package

Then, the first option is going to the other target, General tab, and in Frameworks, Libraries and Embedded Content press +, select the package and press Add:

Adding package in General tab

The other option is going to build Phases and repeat a similar way in Link Binary With Libraries:

Build Phases

Select package

At the moment, I only know this options, I hope in the future Apple could improve this with a multi-check, for example.

Solution 2 - Swift

In addition to the solution diego-carrera gave I had to reset the swift package caches to have the package available for all targets in the framework dialog.

In Xcode: File -> Swift Packages -> Reset Package Caches

Solution 3 - Swift

If you add a new target after you added the dependency, then you will have to remove the dependency from the project and then add it back in again. Otherwise the library will not show up in the framework chooser.

It's annoying that the one reliable thing Xcode can do with Swift Package Manager is crash for me. So make sure you have a backup of the project because it can get to a state that just opening it will crash Xcode.

Solution 4 - Swift

I hit the same problem when trying to add the new Numerics package to my project which contains an iOS Target called CreativeCoding, and a Mac command line target called mandelbrot.

I added the package the normal way in Xcode to the first target. I then quit Xcode and opened up the project.pbxproj file in an editor (vi of course). I then went down to the / Begin PBXNativeTarget section / comment, found my CreativeCoding target and copied the 3 lines from the packageProductDependencies container with the new Numerics packages (Numerics, ComplexModule, RealModule) and pasted them into the packageProductDependencies container of my mandelbrot command line target.

/* Begin PBXNativeTarget section */
            8B083F4B24F0B40000A225C8 /* CreativeCoding */ = {
                    isa = PBXNativeTarget;
                    buildConfigurationList = 8B083F6024F0B40200A225C8 /* Build configuration list for PBXNativeTarget "CreativeCoding" */;
                    buildPhases = (
                            8B083F4824F0B40000A225C8 /* Sources */,
                            8B083F4924F0B40000A225C8 /* Frameworks */,
                            8B083F4A24F0B40000A225C8 /* Resources */,
                    );
                    buildRules = (
                    );
                    dependencies = (
                    );
                    name = CreativeCoding;
                    packageProductDependencies = (
                            8B22BD29263E328B00867530 /* ComplexModule */,
                            8B22BD2B263E328B00867530 /* RealModule */,
                            8B22BD2D263E328B00867530 /* Numerics */,
                    );
                    productName = CreativeCoding;
                    productReference = 8B083F4C24F0B40000A225C8 /* CreativeCoding.app */;
                    productType = "com.apple.product-type.application";
            };
            8BE83F4F26213D1C00663AC9 /* mandelbrot */ = {
                    isa = PBXNativeTarget;
                    buildConfigurationList = 8BE83F5626213D1D00663AC9 /* Build configuration list for PBXNativeTarget "mandelbrot" */;
                    buildPhases = (
                            8BE83F4C26213D1C00663AC9 /* Sources */,
                            8BE83F4D26213D1C00663AC9 /* Frameworks */,
                            8BE83F4E26213D1C00663AC9 /* CopyFiles */,
                    );
                    buildRules = (
                    );
                    dependencies = (
                    );
                    name = mandelbrot;
                    packageProductDependencies = (
                            8BB120942622CCB8008EDAB0 /* ArgumentParser */,
                            8B22BD29263E328B00867530 /* ComplexModule */,
                            8B22BD2B263E328B00867530 /* RealModule */,
                            8B22BD2D263E328B00867530 /* Numerics */,
                    );
                    productName = mandlebrot;

It may have been a little easier for me as I already had the ArgumentParser package on my second target that I just appended the 3 new lines to. However you could do the same and add a temporary package to your second target.

I then went in to Xcode and built the two targets like normal and it worked.

Solution 5 - Swift

With Xcode 12 you just select second target and add dependency (swift package).

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionTruMan1View Question on Stackoverflow
Solution 1 - SwiftDiego CarreraView Answer on Stackoverflow
Solution 2 - SwiftSanzaruView Answer on Stackoverflow
Solution 3 - SwiftJohn EndresView Answer on Stackoverflow
Solution 4 - SwiftBrettView Answer on Stackoverflow
Solution 5 - SwiftsabilandView Answer on Stackoverflow