Pitfalls of manual dependency management in Xcode?

I have given up trying to get Xcode's package manager to work. This is a question about whether my workaround is a bad idea.

(Yes, I know, when SPM works, it works just fine. But recently I needed to update some package versions and spent hours staring at Package resolution failed. The worst part is that it takes 15-30min to fail (fetching, verifying, validating endlessly)! I have tried deleting DerivedData, Packages.resolved, restarting Xcode, resetting the package cache, removing ~/Library/Caches/org.swift.swiftpm, etc.)

My workaround is simple: for each dependency, clone the repo myself and then drag it into Xcode navigator. Add its library to each target's "Frameworks, Libraries, and Embedded Content" section.

This seems to work fine. My question is whether there are pitfalls to this approach?

Answered by sharp11 in 780166022

After more experimentation (including a stab at using Carthage), I hit upon a wonderful solution to this problem. My steps for adding dependencies are now:

  1. Clone the repo into local package_dependencies folder
  2. Check out the specific release (tag)
  3. Under Xcode's Package Dependencies tab, hit the + sign and select "Add local".
  4. Select the folder containing the repo
  5. In the confirmation dialog, select the appropriate target

This works great, fetching and verifying takes only a few seconds (and doesn't re-verify every single package every time!), and I have yet to encounter flaky errors. (Fingers crossed!)

The only downside is that Package.resolved doesn't record specific versions anymore. That's unfortunate but the benefits completely outweigh the loss.

Accepted Answer

After more experimentation (including a stab at using Carthage), I hit upon a wonderful solution to this problem. My steps for adding dependencies are now:

  1. Clone the repo into local package_dependencies folder
  2. Check out the specific release (tag)
  3. Under Xcode's Package Dependencies tab, hit the + sign and select "Add local".
  4. Select the folder containing the repo
  5. In the confirmation dialog, select the appropriate target

This works great, fetching and verifying takes only a few seconds (and doesn't re-verify every single package every time!), and I have yet to encounter flaky errors. (Fingers crossed!)

The only downside is that Package.resolved doesn't record specific versions anymore. That's unfortunate but the benefits completely outweigh the loss.

I wrote a simple post-checkout git hook to capture the currently checked out tag:

#!/bin/sh

# Get the repository name
repo_name=$(basename `git rev-parse --show-toplevel`)

# Get the current tag
current_tag=$(git describe --tags --exact-match 2> /dev/null)

# If there is a current tag
if [ $? -eq 0 ]; then
    echo "$repo_name: $current_tag" >> ../PackageDependencies.history
else
    echo "WARNING: Ignoring post-checkout hook, no tag found"
fi
Pitfalls of manual dependency management in Xcode?
 
 
Q