I R Cubic

The personal blog of Daniel E. Bruce (@ircubic).

Want to contact me? You can tweet me or send an email.

Did I mess up? Want to suggest an improvement? File an issue!

Accessing Swift code in Objective C tests

14 Nov 2014

If you’re working with a mixed Objective C and Swift codebase and you also write tests (if you’re not, you should be), you might need to access your Swift objects from Objective C tests. This does not work out of the box in XCode 6.1 (although accessing them from Swift tests works perfectly well), but I managed to find a workable (though not perfect) solution.

The main issue is that the two most obvious ways of accessing the Swift code of your main target, #import "Module-Swift.h" and @import Module, do not work from your test target. The reason for this is that the header file is an autogenerated file, and therefore only exists in the build directory, and the test target does not see the main target as a framework module to be imported.

The solution I came up with, which is not ideal but works, was to add the folder containing the main target’s autogenerated header file to the test target’s header search paths. Specifically, find the “Header Search Paths” option in the test target’s build settings, and add the following path: $CONFIGURATION_TEMP_DIR/Module.build/DerivedSources. You will have to replace “Module” with your main target’s product name (which you can find in its build settings). The product name can contain spaces, which need to either be escaped or the whole setting line needs to be wrapped in quotation marks.

As mentioned, this is not an ideal solution, because the autogenerated header only reflects the last build of the main target. If you make additions to the main target and want to get proper completion for them while writing tests, you need to build the main target manually before they become accessible. I also don’t know if this is the only way to do it, and would love to know if there is a better way to do it.

In my opinion, this should have been fixed before releasing Swift to the public, as it is a major stopping point for actually being able to safely port Objective C code bases to Swift, which Apple seems to want. I hope to see this supported properly in the future, perhaps by allowing the test target to see the main target as a module or just by extending XCode’s “object location magic” to Swift code as well.