Using XCTest extension in a Swift Package

Rostyslav Druzhchenko
3 min readMay 6, 2021

--

May 2021

Photo by seth schwiet on Unsplash

Many of us aggregate our code snippets and utilities to libraries. Several years ago, Apple provided a good package manager that might be used for this goal — Swift Package Manager (SPM). Undoubtedly SPM is a great tool, but sometimes developers face issues that are difficult to find the reason, and fixing may be tangled and not obvious.

In this short note, I would like to document a workaround for one of these issues.

It looks like:

and text

Undefined symbol: _OBJC_METACLASS_$_XCTestCase
Undefined symbol: _OBJC_CLASS_$_XCTestCase
Undefined symbol: __swift_FORCE_LOAD_$_XCTestSwiftSupport

Since I have not found a working solution on the Internet, I discovered it by myself. I found the reason for this issue and a workaround that I would like to save for myself and probably for other developers who will face this issue.

Scenario

I tried to add a Swift package to my iOS project. Like this

Then Xcode resolved the package’s dependencies; I tried to build the iOS application and gave the build error. After some discovery, I found that the reason is a Swift file in the package that imports XCTest and a class inherited from XCTestCase . I used this class in several other Swift packages, but everything worked well in those packages. The issue appeared only in an iOS application project when I tried to add this package. I have not even used this package; I just added and built it.

To ensure that this class is a source of the issues, I deleted it from the package and upload changes, and the issue has gone. After that, I tried several approaches and finally came up with this workaround.

The Workaround

  1. In the source package, move the file that uses XCTest into a separate target in the Package.swift file.

2. Upload changes and update the package’s version.

3. Then add the package as iOS project’s dependency and select only the target that does not contain XCTest:

4. Then go to the unit test target -> Build Phases -> Link Binary With Libraries and press the gray cross on the left side:

5. Select the library that contains XCTest code and press Add :

6. Build the project.

7. Enjoy yourself.

Conclusions

  1. It’s better to have fixed Swift packages versions everywhere. It simplifies location as a source of an issue.
  2. SPM is still relatively young (about six years) and has some issues. I count a project mature when it crosses twenty years line.

--

--

Rostyslav Druzhchenko
Rostyslav Druzhchenko

Written by Rostyslav Druzhchenko

An experienced software engineer with over 17 years in mobile development. Interested in Swift, iOS, Java and music programming. Skydive as a hobby.

Responses (2)