This is a local package I created to be used by a Mac Catalyst app. The package is cross-platform with three source folders “iOS”, “macOS” and “Shared”. It uses a “bridge” to run AppKit code.
This is the package manifest I came up with. It’s based on my limited experience with SPM, suggestions from AI and comparing others I’ve seen, so I’m not entirely confident with the results. I’m looking for any and all feedback.
import PackageDescription
let package = Package(
name: "FooBuilder",
platforms: [
.macOS(.v11), .iOS(.v16)
],
products: [
.library(
name: "FooBuilder",
type: .static,
targets: ["FooBuilder"]
),
.library(
name: "FooBuilderMac",
type: .static,
targets: ["FooBuilderMac"]
)
],
targets: [
// Shared code
.target(
name: "FooBuilderCore",
path: "Sources/FooBuilder/Shared",
swiftSettings: [
.defaultIsolation(MainActor.self),
.enableUpcomingFeature("NonisolatedNonsendingByDefault"),
.enableUpcomingFeature("InferIsolatedConformances"),
.define("BUILD_LIBRARY_FOR_DISTRIBUTION", .when(platforms: [.macOS, .iOS], configuration: .debug)),
.define("BUILD_LIBRARY_FOR_DISTRIBUTION", .when(platforms: [.macOS, .iOS], configuration: .release)),
]
),
// iOS target
.target(
name: "FooBuilder",
dependencies: ["FooBuilderCore"],
path: "Sources/FooBuilder/iOS",
linkerSettings: [
.linkedFramework("UIKit"),
]
),
// macOS target
.target(
name: "FooBuilderMac",
dependencies: ["FooBuilderCore"],
path: "Sources/FooBuilder/macOS",
linkerSettings: [
.linkedFramework("AppKit")
]
),
.testTarget(
name: "FooBuilderTests",
dependencies: ["FooBuilder"]
)
]
)
This “cross-platform” architecture seems to be working fine. When I add the package to Xcode as “Local” it gives me the option to assign a target membership to both libraries, so I choose:
- “FooBuilder” —> main app
- “FooBuilderMac” —> to our AppKit plugin
Incidentally, I should mention this has been working fine in development (Xcode 26.0 / Sequoia 15.6) but now that I hand it off to QA/PR our Xcode Cloud builds are failing (Xcode 26.1.1 / Tahoe 26.1) : “Multiple commands produce … FooBuilderCore.o”. I’ll upgrade to Tahoe and latest Xcode this evening, in case that is a factor.
This ^^ is obviously a motivating force for making this post, but I also would like general feedback.