How to use the new module disambiguation in Xcode projects?

Swift 5.7 introduced the module disambiguation feature. But the problem I'm having is that how do I use that feature in my Xcode app project? I'm not developing a Swift package, so I don't have the package.swift file. I'm using a package called Regex with a top level class also called Regex, and there seems no way to solve the error of name clashing with the new standard library built in Regex. The WWDC videos only vaguely mentioned this topic, and I can't find any other resources explaining this issue. Am I missing something?

Xcode needs to add support for the feature in its package UI. Unfortunately that doesn't seem to have happened this year so perhaps we'll see it next year.

In the meantime, you could try creating a local Package which renames the module and then vends it using @_exported import NewName in a single source file. Then importing the new package may give access to the Regex types under the imported module name, allowing you to disambiguate.

If it was referenced in the WWDC22 videos, shouldn't it be in the Xcode 14 Beta package UI?

Just because SPM has a feature doesn't mean Xcode's package interface will expose it.

I'm trying to look but Xcode 14b2's package interface just sits on a spinner for me. Cool.

1 Like

Currently the build system that supports module disambiguation is SwiftPM only (see proposal for more info); a new parameter moduleAliases is introduced and can be used as seen here. The parameter is not yet available on Xcode UI, so access to the user package manifest is needed.

If SwiftPM is not used as a build system, a new compiler flag in 5.7 called -module-alias can directly be applied to a build command line to enable module name disambiguation. For example, if module Foo depends on module Bar, and Bar needs to be renamed as Baz, running the following command lines will allow disambiguation:

swiftc -module-name Baz -module-alias Bar=Baz -o /path/to/Baz.swiftmodule
swiftc -module-name Foo -module-alias Bar=Baz -o /path/to/Foo.swiftmodule

The first line will create Baz.swiftmodule which was originally named Bar, and the second line will compile any references to Bar in module Foo as Baz.