Package registry support in Xcode (original) (raw)

I know that Xcode doesn't have explicit support in the UI for Package Registries, but can use packages referenced by ID if the registry is set up through the CLI.

I also see that xcodebuild has support for SCM to registry transformation (resolving and downloading packages through a registry, even if the packages are referenced using their Github URLs) through options like -defaultPackageRegistryURL and -packageDependencySCMToRegistryTransformation. Is there any way to achieve the same thing in Xcode itself?

Hacksaw August 2, 2024, 8:40pm 2

Have you seen in the Xcode add package dialog, at the bottom of the sidebar, the plus button which offers "Add Package Collection"?

Jon_Shier (Jon Shier) August 2, 2024, 9:23pm 3

Package collections aren't registries.

Hacksaw August 3, 2024, 12:25am 4

Fair enough. Are they collections of collections, then?

robinkunde (Robin Kunde) August 4, 2024, 6:08pm 5

Are you familiar with NPM, PyPI, or homebrew (sorta)? Registries are like that. Instead of having to clone the whole repo of the package you're pulling in, SPM can just download a zip file.

robinkunde (Robin Kunde) August 7, 2024, 2:55pm 6

I filed FB14699700 asking Apple add this feature to Xcode to document it if it already exists.

robinkunde (Robin Kunde) August 14, 2024, 2:11pm 7

I got a reply!

This is not yet supported in Xcode directly; but you can handle this with an environmene variable in your scheme:
-IDEPackageDependencySCMToRegistryTransformation={the same value supplied to the CLI}

valentary (George Brown) October 3, 2024, 3:21pm 8

I'm also struggling with adding a package registry to an xcode project. I made a little progress using IDEPackageDependencySCMToRegistryTransformation , but I need to set the scope and i'm not sure how it should be done.

Equivalent to swift package-registry set --scope <scope> <registry-url>

Does anyone have any idea how to do that?

Karsten_Bruns (Karsten Bruns) October 3, 2024, 4:09pm 9

Not sure if this helps you to find a solution. Last time I played with registries I made it work by editing the content of the .swiftpm folder in the xcode project bundle so it contains the changes that you usually do via the swift package commands.

valentary (George Brown) October 4, 2024, 8:33am 10

I'm finding it very hard to get it working reliably even in a package, I'm never sure what combination and order of cleaning caches, running swift commands and logging in get's it to work even on a package.

In my case, I'm trying to get it to work with jfrog Artifactory JFrog Help Center

valentary (George Brown) October 4, 2024, 12:32pm 11

Adding the registries json file from a working package to the xcworkspace is indeed what got it working for me, thanks! (Or at least progressed, the package is now downloading to the cache, it's failing for another reason...)

This is where to put it:

├── WorkspaceSettings.xcsettings
└── swiftpm
    ├── Package.resolved
    └── configuration
        └── registries.json

I initialy got a git shell error 128 during package resolution, but this just required the swift package-registry login <url> command to be run again to fix it.

robinkunde (Robin Kunde) October 4, 2024, 7:13pm 12

I had a half-written blog post about this somewhere. Let me see if I can find it.

valentary (George Brown) October 9, 2024, 8:06am 13

Found my issue, and as it was still related to the registry, I'll add it here.

I was using a method similar to how amazon analyze the root of the package to find the binaries and add the products and targets in the Package.swift file when they're working locally.

aws-sdk-ios-spm/Package.swift at 5a7f1036ca625cc9dcee8cdc6aff7c60f2214664 · aws-amplify/aws-sdk-ios-spm · GitHub

In all other circumstances this seems to work, except when pulled through the package registry, when it would fail to add the products and targets, probably #file was not working correctly, I'm not sure how I would go about debugging it.

This was handy workaround as we're building a c++ library with multiple layers of dependencies, and not having to update the Package.swift with changes was useful.

Likely I will now figure out something with swift code gen when building the package.

valentary (George Brown) October 10, 2024, 9:47am 14

This continues to be challenging. Some further issues I have resolved trying to get this to work in an XCode project.

The package I'm vending through the package registry is one depended on by higher level packages, so the project doesn't have a direct reference to the low level package, it is only through the high level packages.

I was working with these high level packages added as local packages to the project while I tried to get everything working. using a branch in each repo (let's say package-registry-update)

Now, I got everything working like that, I removed the local references to the high level packages from the project, and told them all to instead resolve to the package-registry-update branch of the repos in github.

This starts causing errors during package resolution of the project with errors like could not find a branch named ‘package-registry-update’ in git@github.com:org/high-level-package-1.git

Thinking I'd hadn't pushed them or somehow had some weird security setting, I messed around in git for ages, but couldn't find anything.

So, thinking maybe If I still had a local package that had the package registry as a dependency, it might solve the issue, which indeed it did. I think this is the solution described at the end of this post : What is Swift-Package-Registry? – Lukas Pistrol

However, I tried that earlier and it simply wouldn't work, only adding the config file in the .swiftpm directory did anything.

I feel these problems are due to the multiple levels of dependency I'm running, and the multiple steps it takes to work on packages in an xcode project, but maybe someone will find this useful in the future.

valentary (George Brown) October 11, 2024, 2:18pm 15

Something I was not aware of. When you use the --global option for swift package-registry set it places the registries.json file in ~/.swiftpm/configuration/

This directory is an alias to one of the spm caches, and if you clean out your caches, you lose your global configuration. I was not aware of this and I think this might have caused me much grief.

fortmarek (Marek Fořt) December 11, 2024, 6:31pm 16

Do those xcodebuild options work for anyone?

I would have expected that xcodebuild -resolvePackageDependencies -packageDependencySCMToRegistryTransformation useRegistryIdentityAndSources -defaultPackageRegistryURL {registry-url} would be the equivalent of swift package --replace-scm-with-registry --default-registry-url {registry-url} but while the swift package ... command does install the packages from the registry, xcodebuild still uses source control instead.

robinkunde (Robin Kunde) February 4, 2025, 6:01pm 17

I remember this "working" in Xcode 15.4. The code paths were executed at least, but some SPM bugs prevented packages from being resolved correctly. Xcode 16.2 doesn't behave the same way anymore. It ignores registries.json but even if you specify everything via command line, it doesn't work.

I can get it to produce errors like the below:

product 'Logging' required by package 'cocoalumberjack' target 'CocoaLumberjackSwiftLogBackend' not found in package 'swift-log'. Did you mean '.product(name: "Logging", package: "apple.swift-log")'?

This indicates it's hitting some related code path, but the registry related cache folders are never created, so it's hard to tell what it's actually doing.

Part of the issue may be how the CLI parameters are handled internally. Since you can configure many settings via user defaults or env vars as well, Xcode has some mechanism for tying these different methods together. If you use a wrong value for -packageDependencySCMToRegistryTransformation, you get this error.

Could not initialize package support: Invalid source control transform ‘blah’ provided for user default ‘IDEPackageDependencySCMToRegistryTransformation’ (expected `none`, `use-registry-identity-for-scm`, or `replace-scm-with-registry`).

Those are the SPM CLI parameters, which xcodebuild does not accept. It wants you to use useRegistryIdentity and useRegistryIdentityAndSources instead. It looks like it was done in a hurry.

As an aside, with the hint to the user defaults key name above, you can actually get Xcode itself to hit the same code paths.

defaults write com.apple.dt.Xcode IDEPackageDependencySCMToRegistryTransformation useRegistryIdentityAndSources

But as far as I can tell, it doesn't work either.

fortmarek (Marek Fořt) March 28, 2025, 9:59am 18

This actually does seem to work, at least in my case. It would have been amazing if this setting could be set on a per-project basis, not just locally. Maybe later this WWDC :sweat_smile:

brunokoga (Bruno Koga) June 11, 2025, 4:17pm 19

I was having the same issue where swift build would work, but xcodebuild (or building within Xcode) didn't – Xcode was not fetching the packages from the registry (in my case, AWS CodeArtifact).
The solution, as described here, was to copy the contents of .swiftpm/configuration/registries.json into MyProject.xcworkspace/xcshareddata/swiftpm/configuration/registries.json (note that the destination swiftpm folder doesn't start with a ".") and create a "Dependencies" package inside my workspace that requires the package from registry and add this "Dependencies" package under the "Frameworks and Libraries" on the correct target of my main project.

Reported to Apple with FB17939830.

Jon_Shier (Jon Shier) June 11, 2025, 5:04pm 20

Xcode 26 also doesn't seem to properly support registries. Guess we get to wait another year.