Search code examples
iosswiftswift-package-manager

How do I add a Swift package that references classes in my main Xcode project?


My main goal is to make a swift package with two states that are toggled on and off by a flag.

One of the states enables code that references classes and variables defined in another project of mine that imports this package. These sections of code are my own personal version of the library with special functionality specific to my project. The other state disables those code sections and enable code that allows the package to be used as library for the general public.

The way I've tried to do this is by using preprocessor macros to turn sections of code on and off. The following flag is defined in a custom branch of my package that I use when I add this package into my other project:

(Package.swift file in my swift package)

swiftSettings: [
  .define("FULL_WEEKDAY_PICKER"),
]),

(code in my swift package)

#if FULL_WEEKDAY_PICKER
// use code referenced in my other project
#else
// do other thing
#endif

This does not work however, and I get errors, because my package has no knowledge of the code in my other project. My first idea was to add it as local dependency to this package. My project has a git repository.

dependencies: [
    // Dependencies declare other packages that this package depends on.
    .package(path: "../HueCircadianSchedule"), // <--- name of my other project
],

.target(
    name: "DayOfWeekCollectionView",
    dependencies: ["Sol"], //<--- target of my other project

But even adding these settings crashes Xcode for me, so I don't think this is the right step to take.

Alternatively, I tried dragging and dropping my package into my other project. I don't get any errors in my package, but the project has no knowledge of the code in the package I just dropped in.

How do I reference code defined in my project in my package and then use that package in my project? Do I need a Package.swift in my project? Should I be taking a different approach to accomplish what I'm trying to do? You can look at my projects here:

My project

My swift package


Solution

  • It sounds like your package is not a proper stand-alone package. Re-design it to be a true stand-alone package, i.e., either move all the required code from your other project into the package, or allow the package's user to extend the package's functionality somehow.

    Basically instead of the package referencing external stuff directly, allow the external stuff to make itself known to the general services of the package. For example, define a protocol in the package and the entity (data source, UI, delegate, or whatever it is) conforming to the protocol in your project. Then you supply that thing when you use the package, and the package only needs to know the interfaces defined in the protocol.

    Or, alternatively, refactor the package in such a way that it doesn't need call any external thing, but rather the external thing calls the package.