I came across a situation today where I needed to run an iOS test suite for a Swift Package. Previously, this required you to have an Xcode project but it no longer does.

I’m not entirely sure when this changed, but before, if you had a Swift package that supported iOS then the only way to build, run, and test that package was to have an Xcode project. Only having a Package.swift file would not suffice. The Swift Package Manager could generate a project for you.

swift package generate-xcodeproj
xcodebuild test -project MyPackage.xcodeproj -scheme MyPackage -sdk iphonesimulator15.0 -destination "OS=15.0,name=iPhone 13 Mini"

Since it has been awhile since I’ve needed to do this, I wanted to see if there have been any changes. Luckily, there have and you no longer need an Xcode project for building and testing. This older thread on the Swift Forums explains. The generate-xcodeproj command has been deprecated, and you’ll get a warning when using it.

If you have only a Package.swift, you can build and test via xcodebuild similar to how you would with a Xcode project. First, run xcodebuild -list to find valid schemes from the package. Then invoke xcodebuild with the desired scheme. Note that no project needs to be specified.

xcodebuild test -scheme MyScheme -sdk iphonesimulator15.0 -destination "OS=15.0,name=iPhone 13 Mini"

This makes working with iOS packages much nicer, especially for non-UI iOS libraries where you never need to actually run on a simulator. This also simplifies running tests on CI.

Update 17 November 2021

Reader Bernd Rabe has pointed out that testing packages this way prevents Xcode from collecting code coverage results, which I have also noticed. You win some, you lose some, I guess. I do not know of any workarounds at this time. If you need code coverage, you will need to keep using an Xcode project.