Objective-C targets within a Swift package

While modularizing a codebase, you may encounter Objective-C code that you'd like to move out of your app's target and into a target within a Swift package that your app target depends on.

With Swift dependencies, this is straightforward:

  1. Create a folder inside the Sources directory of the Swift package.
  2. Delete the references to the Swift files you'd like to move over from the main target.
  3. Drag and drop the files from their location in the main target to the folder you just created in Sources.
  4. Update the Package.swift to reference the new folder:
  5. let package = Package(
      name: "...",
      platforms: [...],
      products: [
        .library(name: "YourNewLibrary", targets: ["YourNewLibrary"]),
    		...
    	],
    	dependencies: [...],
    	targets: [
    		.target(name: "YourNewLibrary",
    		dependencies: [...],
    		path: "Sources/YourNewLibrary")
    		...
    	]
    )

With Objective-C dependencies, the steps are exactly the same as above. However, we have to help Swift Package Manager identify where the dependency's header files are located. To do this, you can either:

  • Create a folder called include within your target folder (e.g. Sources/YourNewLibrary/include/) and move your Objective-C header files into that folder.

Or

  • Specify a custom path for the headers folder using publicHeadersPath (this is set to include by default). For example:
  • .target(name: "YourNewLibrary",
    dependencies: [...],
    				path: "Sources/YourNewLibrary",
    publicHeadersPath: "Core/headers/")

With either option, all Objective-C headers must be located within the same directory, and this directory cannot contain any implementation files.

Apple Developer Documentation - publicHeadersPath