Imagine you’re working on Project A, which relies on Package B, a remote Swift package. To incorporate modifications in B and assess their impact on A, the standard approach requires committing and pushing the changes in B, updating B’s version in A, and then rebuilding A to observe the outcomes. This method is slow and cumbersome. There must be a better way!

Project A
  |
  └──> Swift Package B

To speed up and improve the workflow, you can convert the remote dependency B to a local one. This method works whether Project A is a Swift package or an Xcode project (xcodeproj or xcworkspace).

Xcode Project

In this case, Project A has an Xcode project file.

  1. Remove the remote dependency from your project.
  2. Re-add it as a local package.

hello there

This might seem excessive, as Xcode also supports just dragging and dropping the package into your project, but I’ve found this solution to be flaky. Explicitly removing it works every time, most of the time.

Swift Package

If Project A is a Swift package, you’ll need to convert B’s dependency declaration:

dependencies: [
    .package(url: "https://github.com/TinyCorp/B", exact: "0.52.3"),
    // ...

… into this:

dependencies: [
    .package(path: "path/to/B"),
    // ...

Example: given the following file structure, path is ../B:

.
├── A
│   └── Package.swift (we're here)
└── B
    └── Package.swift

With this setup, you’re now able to edit dependency B directly inside of A. I was genuinely surprised by how well Xcode handles this workflow.

Notes

Make sure the Swift package that you plan to add to your project is not opened in another Xcode window. In some cases, Xcode might fail with a cryptic error when trying to add the local package.