Objective-C Helper Headers in Swift Packages

I have a Swift library that I’m retrofitting to add support for SPM. One of the things that the Swift library does is support for calling the library from Objective-C. To do that, I needed to make a header file to define an option type in Objective-C, which is then imported into Swift:

/// An option type representing the sides of an on-screen view.
typedef NS_OPTIONS(NSUInteger, BSPViewEdge) {
    
    /// No edges
    BSPViewEdgeNone   = 0,
    
    /// The top edge of the view
    BSPViewEdgeTop    = 1 << 0,
    
    /// The left edge of the view
    BSPViewEdgeLeft   = 1 << 1,
    
    /// The right edge of the view
    BSPViewEdgeRight  = 1 << 2,
    
    /// The bottom edge of the view
    BSPViewEdgeBottom = 1 << 3
    
} NS_SWIFT_NAME(ViewEdge);

/// All four edges of a view.
NS_SWIFT_NAME(ViewEdge.all)
static BSPViewEdge const BSPViewEdgeAll = (BSPViewEdgeTop |
                                           BSPViewEdgeLeft |
                                           BSPViewEdgeRight |
                                           BSPViewEdgeBottom);

/// The bottom, left, and right edges of a view.
NS_SWIFT_NAME(ViewEdge.bottomEdges)
static BSPViewEdge const BSPViewEdgeBottomEdges = (BSPViewEdgeLeft |
                                                   BSPViewEdgeRight |
                                                   BSPViewEdgeBottom);

If I build the Swift package as-is, it can’t find the ViewEdge type.

First, I tried creating a new target, BottomSheetPresentationLegacySupport:

let package = Package(
    name: "BottomSheetPresentation",
    platforms: [.iOS(.v8)],
    products: [
        .library(name: "BottomSheetPresentation",
                 targets: ["BottomSheetPresentation"]),
        .library(name: "BottomSheetPresentationLegacySupport",
                 targets: ["BottomSheetPresentationLegacySupport"])
    ],
    targets: [
        .target(name: "BottomSheetPresentationLegacySupport",
                dependencies: []),
        .target(name: "BottomSheetPresentation",
                dependencies: ["BottomSheetPresentationLegacySupport"]),
        .testTarget(name: "BottomSheetPresentationTests",
                    dependencies: ["BottomSheetPresentation"]),
    ],
    swiftLanguageVersions: [
        .version("4"),
        .version("4.2"),
        .version("5")
    ]
)

I placed the header file in the include/ folder in the LegacySupport target. Building with swift build -Xswiftc "-sdk" -Xswiftc "$(xcrun --sdk iphonesimulator --show-sdk-path)" -Xswiftc "-target" -Xswiftc "x86_64-apple-ios13.0-simulator" produces the following:

error: target 'BottomSheetPresentationLegacySupport' referenced in product 'BottomSheetPresentationLegacySupport' could not be found

I’m guessing this is because there’s no module being produced. I created an empty Objective-C file called dummy.m and placed it in the source folder for the target and that target compiles! Now, I can add the following to my main Swift files:

#if SWIFT_PACKAGE
import BottomSheetPresentationLegacySupport
#endif

Now, my actual question: Is there a way to create header-only targets such that I don’t need the dummy.m file?

@Aciid What do you think? Independently from that, do you think we should improve the diagnostic?

error: target 'BottomSheetPresentationLegacySupport' referenced in product 'BottomSheetPresentationLegacySupport' could not be found

feels like SwiftPM can't find the target, but its there.

Terms of Service

Privacy Policy

Cookie Policy