Xcode ignoring Package.resolved file

I'm unsure if this is an SPM issue or Xcode issue but one of the most frustrating experiences of using SPM with Xcode is how frequently it ignores the Package.resolved file in my repo, often when switching branches or between different machines.

The Package.resolved file should be the source of truth for my dependencies and it should never be ignored - fail package resolution if there's a problem, but don't EVER change my dependencies.

What seems to happen is that Xcode will just prefer to use whatever version of a library exists in its source cache that happens to fulfil the package version requirements rather than what is in the resolved file. For example, I have a library with the version requirements "2.2.0 up to next minor". The Package.resolved file has 2.2.3 in it so this is the version I expect to be used ALWAYS unless I make some changes that would introduce a conflict. When I open the same project up on a different machine, for some reason it insists on changing to 2.2.2, presumably this is the version in its cache. WHY? What is the point of having a resolved file if it can be ignored?

8 Likes

I've recently seen this as well and it's truly baffling. I just went through and updated all of my project package inclusions to start at the latest version. Annoying, but fixed the immediate problem. Since it's not something that will be fixed for Xcode 14 I guess we have to see if Xcode 15 helps here and, if not, file bug reports in hopes that it can get fixed in the 8 week window we have.

1 Like

Additionally, this isn't something I ever saw before Xcode 14.3, so it may be a regression there or in the underlying Swift 5.8 libSPM.

I suspect this might be the fix [5.9] Revert "missing pinned version" change by neonichu · Pull Request #6578 · apple/swift-package-manager · GitHub

3 Likes

So glad to hear there's a fix coming! In the meantime, I have found that deleting the workspace-state.json file found under ~/Library/Developer/Xcode/DerivedData/*/SourcePackages/ before switching branches forces Xcode to do the right thing with Package.resolved.

1 Like

Will we need a new Xcode release to fix this? I assume so, but is there a chance this could be in a point release before WWDC (so it could also fix the concurrency issue @Douglas_Gregor mentioned there is a fix for in the other thread, two bugs with one stone :))?

I am thinking about CI builds where we may have more than one build per build agent…

I could be missing some detail, but at the time when updating to Xcode 14.3 and facing this issue in our CI, we realised we never called xcodebuild with the -onlyUsePackageVersionsFromResolvedFile flag. Now we do, and the CI seems to respect our Package.resolved file.

For us, this issue only exists in the GUI of Xcode. (At the same time, I'm equally baffled why -onlyUsePackageVersionsFromResolvedFile is needed and not the default mode for both the CLI and the GUI!)

2 Likes

Will double check that thanks :).

Hello @pyrtsa @NeoNacho do you know the difference between these two options for xcodebuild please? From xcodebuild's help command:

-disableAutomaticPackageResolution prevents packages from automatically being resolved to versions other than those recorded in the Package.resolved file

-onlyUsePackageVersionsFromResolvedFile prevents packages from automatically being resolved to versions other than those recorded in the Package.resolved file

We said that the latter fixes this issue in CI, but I think the former should do too... right :)?

1 Like

I believe they're synonymous. The one I mentioned was introduced a little later and I think is a bit less ambiguous.

1 Like

It’s been doing this since SPM support was added.

It also seems to add and remove .git suffix from the url in the package resolved file without any rhyme or reason.

One of the easy ways to break your package.resolved file is to create a merge conflict in your project.pbxproj file.

Seems Xcode uses this file when resolving your packages. So when there’s a merge conflict. It can’t resolve your packages and thus deletes your package.resolved file.

Once your merge conflict is fixed, Xcode regenerates the .resolved file. Often updating packages in the process if you are using .untilNextMajor versioning.

It’s incredibly frustrating.

The more I work with stand-alone swift packages, the more I wish I could just use a Package.swift file to build iOS projects. As the old Xcode project manifests are horrible to work with.

6 Likes

After version 14, every time I open a project Xcode resolve / download all packages again even if there are no changes.

Hope for a fix.

Also we need a modern (and made from ground) Xcode exclusive for Swift. Is getting heavy year after year.

1 Like

Would love to see apple open source the iOS/tvOS/etc... SDKs so that the community could build proper iOS dev support into VSCode or other popular IDEs.

1 Like