I\'m trying to work on a mixed Swift and ObjectiveC project with no luck.
My project is made of 6 targets:
This is not a solution for the question but since many might end up on this page looking for the problem that the <ModuleName>-Swift.h
file is not found (just like me) I'd like to add one more possible reason:
When there is a compiler issue in a swift file the header might not get generated by Xcode and thus the file is missing.
At least in my case the <ModuleName>-Swift.h not found
was gone once I fixed the compile error in the Swift file.
For my case, it runs fine in Xcode 8 but files with
#import "Project-Swift.h"
has missing imports as described by LucioB
Using Xcode 9 removes those errors
In my case, I declared import statement into .h file
Then I change
#import "ProjectName_App-Swift.h"
into implementation file(.m)
Clean and restart Xcode Working
The solution for me was to import the generated swift header via <>
syntax:
#import <OtherTargetWithSwiftClass/OtherTargetWithSwiftClass-Swift.h>
The assumption I made in Edit 4 turned out to be the correct one. If a project has multiple targets the "-Swift.h" files cannot be imported all in one .m ObjectiveC file.
So there is one solution that must be adopted and it is to change the SWIFT_OBJC_INTERFACE_HEADER_NAME build setting and making it the same across different targets. To do so change the instruction that generates this property from $(SWIFT_MODULE_NAME)-Swift.h to $(PROJECT_NAME)-Swift.h as explained here
It is also possible to set the Product Module Name setting in Build Settings to be the same across your modules (I set it to $(PROJECT_NAME)), so that the -Swift.h file that is generated has the same name across all modules. This eliminates the need for adding/checking preprocessor macros.
After doing this Clean Build Folder by pressing Alt and going into Product menu. Since name of header is shared among targets now it can be imported once in the .m ObjectiveC file and all targets can benefit from Swift classes.
If after building it still shows the error, ensure that the header can be reached from XCode by Cmd clicking on its name. It should open a file that contains code similar to this:
SWIFT_CLASS("_TtC27ProjectName_Summary11MyClass")
@interface MyClass : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end
If need to ensure that those headers are being generated open a terminal and use this command
find ~/Library/Developer/Xcode/DerivedData -name "*Swift.h"
You should see one header for each target
Another issue that happened to me after those changes is that it started giving errors on ObjectiveC code that I didn't touch. The problem was due to the position of the import, as reported here:
Exactly where at the top of a .m file you #import the hidden bridging header can make a difference. The usual sign of trouble is that you get an “Unknown type name” compile error, where the unknown type is a class declared in Objective-C. The solution is to #import the .h file containing the declaration for the unknown type in your Objective-C files as well, before you #import the hidden bridging header. Having to do this can be an annoyance, especially if the Objective-C file in question has no need to know about this class, but it resolves the issue and allows compilation to proceed.
At the very end the code compiles and runs on device and simulator!
In my case, I have a workspace with an iOS app subproject, a framework subproject, and a CocoaPods Pods subproject. The "ModuleName-Swift.h file not found" error occurred in my framework subproject because the file hadn't yet been created by the Pods subproject.
I'm not sure if there's a way to tell Xcode about dependencies between subprojects, but I simply re-ordered them in the left-side Project Navigator:
Worked great after that!