By changing the 'PRODUCT_MODULE_NAME' build setting + adding XCTest.h import in the bridging header file, I was able to make this work.
On my previous post about Swift, I mentioned that one of the biggest issues I had with Swift is the fact I get a compilation error on my unit tests target if I ever use the import "MyProject-Swift.h" in a file that is included in this target (whether it's a test case or production code).
I also mentioned this is a big issue in the Swift talk I gave in Reversim Summit 2015 (in Hebrew).
Well, turns out I was wrong (or at least - it can be fixed).
To fully understand the solution, lets' first make sure you understand the problem and why this is such a big issue for me.
I'll try to show a concrete example so you could understand it, and maybe because all names are stupid it may be harder to relate to, but believe me - if you write new swift code in a real life Objective-C project, you will eventually need to use it SOMEWHERE from your Objective-C code.
Class A is written in Objective-C and has a unit test.
It also internally uses a class called B, written in Objective-C and doesn't have a unit test.
I now decided I want to add a new class named C. It's written in Swift and I add a unit test for it in Swift.
Now I want to use class C in class B.
I need to add "MyProject-Swift.h" to B's code for it to work, right?
Right.
So here's what we've come up with by now:
If I build and run my app, everything is fine.
If I build and run my unit tests target, I get the following error:
![]() |
'MyProject-Swift.h' file not found |
When I originally found out about this (somewhere during the early days of Xcode 6), I was helpless and devastated.
There were only 3 workarounds I could think of and apply to my projects:
- Not importing "MyProject-Swift.h", and therefore having to use tricks like NSClassFromString(@"C") and performSelector - UGLY as hell
- Removing B.m from the Test target (by unchecking the target in the "Target Membership" section of the File Inspector) - Might work for certain cases, but as you see in my example, this means ATest can't compile as it uses A that uses B (that uses Swift code). So if I have enough coverage in my unit tests this is hopeless.
- Porting the whole project to Swift - Too expensive.
This essentially meant that I used swift only for very isolated features in my project, which was very upsetting.
The reason I originally came to the conclusion that it can't be fixed and there aren't any other workarounds, apart from banging my head for a long time about it without success, was an answer on SO basically saying that Apple declared it's a known issue.
In a weird coincidence, just several hours before I decided I should tackle this issue again, a new answer was posted to the same question. It didn't quite solve my problem (I think it's because I didn't move to Xcode 6.3 yet for the problematic project), but it gave me the hope and the direction to a solution!
The Solution
What essentially happens, is that the name of the generated header file that contains all the exported classes from Swift to Objective-C, is called "${PRODUCT_MODULE_NAME}-Swift.h"
What's ${PRODUCT_MODULE_NAME}? By default, Xcode sets it to be the same as the ${TARGET_NAME}, meaning: MyProject-Swift.h for the App target, and MyProjectTests-Swift.h for the test target.
So, we could use some #ifdef statements each time we want to include the generated Swift header, but this is a terrible solution. Instead, I manually changed the product module name the following way:
![]() |
PRODUCT_MODULE_NAME = "MyProject" |
That's it. For the example project I created for this post it was all I needed to do for solving the problem.
In my real project however, possibly because it was created with an older version of Xcode, I had another issue that I thought was worth mentioning - an issue of Xcode suddenly not running my Swift unit tests (CTest.swift in this example). It was complaining about not finding XCTestCase in the generated MyProject-Swift.h file.
What eventually solved it for me, is adding an XCTest import in my "MyProjectTests-Bridging-Header.h" file in the following way:
![]() |
Add #import <XCTest/XCTest.h> to MyProjectTests-Bridging-Header.h
|
And that's it - problem solved.
BTW
If you are having problems with the other way around (Swift code importing Objective-C code in Unit Tests), I recommend reading the following post.
Also, if you have found this post interesting, you should follow me on twitter and listen to my podcast (in Hebrew).
Hi thanks for the post. I'm in a similar situation (trying to write swift tests including Obj-C files that use Swift code) and I got past the error you're getting by following this SO post: http://stackoverflow.com/questions/26473058/ios-myproject-swift-h-file-not-found-when-running-unit-tests-for-swift/29111547#29111547
ReplyDeleteHowever I'm now getting a different type of linker error:
"_OBJC_CLASS_$__TtC10AppName20ClassA", referenced from:
objc-class-ref in ClassB.o"
Any idea what this could be? Thanks!
I'm the same problem here. Did you manage to solve this?
DeleteThanks
This comment has been removed by the author.
DeleteIEEE Final Year Project centers make amazing deep learning final year projects ideas for final year students Final Year Projects for CSE to training and develop their deep learning experience and talents.
DeleteIEEE Final Year projects Project Centers in India are consistently sought after. Final Year Students Projects take a shot at them to improve their aptitudes, while specialists like the enjoyment in interfering with innovation.
corporate training in chennai corporate training in chennai
corporate training companies in india corporate training companies in india
corporate training companies in chennai corporate training companies in chennai
I have read your blog its very attractive and impressive. I like it your blog. Digital Marketing Company in Chennai
Yes
ReplyDeleteSee tl;dr at the beginning
Hi,
ReplyDeleteThanks for the post,Really you given a valuable information.worth to read this type of articles .very grateful to you for sharing this article.
Thank you.
oracle fusion training
Nice post!! Thanks for sharing.
ReplyDeletedermology hair removal cream
Pretty article! I found some useful information in your blog, it was awesome to read, thanks for sharing this great content to my vision, keep sharing..
ReplyDeleteMobile App Development Company
Mobile App Development Company in India
Android app Development Company
ios app development Company
Mobile App Development Companies
This article is very much helpful and i hope this will be an useful information for the needed one.Keep on updating these kinds of informative things... iPhone Development Company
ReplyDeleteExcellent Post! Thanks for sharing the information. Very informative blog post.
ReplyDeleteTaxi App Development
thank you for a great post.
ReplyDeleteAndroid App Development Houston
Here are 6 steps how to complete a project handoff.
ReplyDeleteI am overwhelmed by your post with such a nice topic. Usually, I visit your blogs and get updated with the information you include but today’s blog would be the most appreciable...
ReplyDeleteThanks
Cpa offers
I'm looking for good blog sites to study. I was looking on the search engines and found your blog site. I like your design of high quality blog sites, as well as your display capabilities. Keep doing it.
ReplyDeleteDedicatedHosting4u.com
Its good and Informative.Thank you for posting this article.
ReplyDeleteios app development course
Hey Good Post!! Thank You For Sharing!!!Good Blog.Its really helpful for me, waiting for a new post. Keep Blogging!
ReplyDeletewill help you more:
Hire some best dancers for your wedding party event or birthday celebration.
Contact Dynamic Hip-Hop And Western Dance Institute, Indore.
Excellent information with unique content, it is very useful to understand blog-based information.
ReplyDeleteMobile App Development Companies in UK
Mobile App Development Companies in California
Mobile App Development Companies in Italy
Mobile App Development Companies in Indonesia
Mobile App Development Companies in Jakarta
Mobile App Development Companies in Norway
Mobile App Development Companies in Sweden
Mobile App Development Companies in Turkey
Thanks for sharing the information.
ReplyDeleteAndroid App development & iOS App development company in Switzerland-Bern
Artificial Intelligence & Iot app development company in Switzerland
Thanks for sharing such a nice information and it is really useful
ReplyDeleteDigital Transformation in Education industry
https://whitelabelfox.com/ubereats-clone-app/
ReplyDeleteCome up with a great learning experience of Azure training in Chennai, from Infycle Technologies, the best software training institute in Chennai. Get up with other technical courses like Data Science, Selenium Automation Testing, Mobile App Development, Cyber Security, Big Data, Full Stack Development with a great learning experience and outstanding placements in top IT firms. For best offers with learning, reach us on +91-7504633633, +91-7502633633
ReplyDeleteThank you for sharing such a informative post.
ReplyDeleteIf you looking for a best pharmacy app development , EMed Healthtech provide readymade and customized online pharmacy app development for different pharma business types.
ReplyDeleteAmazing blog! Thank you for sharing.
Alteza is a leading online pharmacy app development company and we address every concern of our clients by providing comprehensive online pharmacy apps for their business needs.