171

I have a project that was started in Objective-C, and I am trying to import some Swift code into the same class files that I have previously written Objective-C in.

I have consulted the Apple docs on using Swift and Objective-C in the same project, as well as SO question like this, but still no avail: I continue to get the file not found error after putting in #import "NewTestApp-Swift.h" (NewTestApp is the name of the Product and module).

Here is what I have done so far:

  1. In Define Modules, selected YES for the app.
  2. Ensured that the Product Module name did not have any space in it (see screenshot below question)

I have tried using #import "NewTestApp-Swift.h" inside ViewController.m, ViewController.h and AppDelegate.m but none of them has worked.

What else am I doing incorrectly? Thanks for your help.


Screenshot of settings:

enter image description here


Errors that I am presently encountering:

enter image description here

Community
  • 1
  • 1
daspianist
  • 5,336
  • 8
  • 50
  • 94

21 Answers21

196

I was running into the same issue and couldn't get my project to import Swift into Objective-C classes. Using Xcode 6, (should work for Xcode 6+) and was able to do it in this way:

  1. Any class that you need to access in the .h file needs to be a forward declaration like this:
@class MySwiftClass;
  1. In the .m file ONLY, if the code is in the same project (module) then you need to import it with:
#import "ProductModuleName-Swift.h"

Link to the Apple documentation about it.

Paulo Mattos
  • 18,845
  • 10
  • 77
  • 85
bolnad
  • 4,533
  • 3
  • 29
  • 41
  • in .h file forward declaration of the class without imporing .h file did the trick for me. Thanks – Sikander Jan 25 '18 at 15:58
  • 4
    Note that if your product name has a `-` character in it, the name of the generated header file will have that converted to `_`. e.g. if your product name is `My-App`, you would import `My_App-Swift.h`. – dvanoni Aug 08 '18 at 14:39
  • 13
    I found a new way to find the correct generated header file name: ***go to your target -> Build Settings -> Search keywords `Objective-C Generated Interface Header Name`***, bingo! – Itachi Dec 21 '18 at 03:35
  • Can someone clarify the first point? Where exactly does the forward declaration go? – rmp251 Aug 07 '19 at 04:45
  • 3
    I've done both of these things, and am still seeing the same issue. Do you think it has to do with the order? – ArielSD Sep 16 '19 at 19:28
  • This definitely fixed it. As far as I can tell I shouldn't need to do this to get it to work, but this works, for sure. – KeithTheBiped Aug 11 '20 at 06:33
100

If the Swift code is inside a Module (like in your case):

#import <ProductName/ProductModuleName-Swift.h>

If the Swift code is inside the project (mixed Swift and ObjC):

#import <ProductModuleName-Swift.h>

In your case, you have to add this line in the *.m file:

#import <NewTestApp/NewTestApp-Swift.h>

IMPORTANT: look at the "<" in the import statement

https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html

Cœur
  • 37,241
  • 25
  • 195
  • 267
ikocel1
  • 1,212
  • 1
  • 9
  • 9
  • Thanks for answering @ikocel1. Unfortunately these didn't work. I've tried variations of ``, `` and `` all inside `ViewController.m`, but continue to get the "file not found" error, despite `Cleaning` the project each time after trying a combination. I have included a screenshot in the body of the question in case it helps. – daspianist Oct 13 '14 at 15:08
  • I have not yet entered any Swift code yet into `ViewController.m`. I have been only trying to import the headers first to try to get it to accept Swift code. I will be mix and matching both Objective-C and Swift code in `ViewController.m`. – daspianist Oct 13 '14 at 15:14
  • 1
    I don't know if its possible to mix directly objc code and swift code in the same file. – ikocel1 Oct 13 '14 at 15:16
  • 1
    Thanks, I guess this was the assumption that I had based on Apple's "Mix and Match" document.. but I guess not inside the actual file. Thank you! – daspianist Oct 13 '14 at 15:27
  • 6
    I did not get why this answer was approved. Yes, it is correct following the documentation but practically does not work for me too. Even in the question it is obvious that the user use the syntax as it is recommended on the this answer but still gets an error. – Darius Miliauskas Mar 11 '15 at 03:25
  • My project was correctly set up, but I was unable to import this header using the `"ProductModuleName-Swift.h"` way. Thanks for the pointer! – Daneo Jun 21 '17 at 06:58
  • 2
    Be careful if your productmodulename contains strange characters. Mine contained a minus and Xcode change the generated filename to use an underscore instead of a minus. Thus say my product module name was `pjh-test`, I needed to `#import "pjh_test_Swift.h"`. I only picked this up after examining the `Objective C Generated Interface Header Name` in the target build settings. Before correcting this I was getting a `file not found` on the import – Paulus Dec 30 '17 at 12:23
62

How I managed to import swift into objective-c:

  • Defines Module set to YES (on project - not on target)
  • Product Module Name set (on target - not on project)
  • In your ViewController.m import the swift code with:

    #import "MyProductModuleName-Swift.h"
    
  • Add a swift file to your objective-c project (File -> New -> Swift) and Xcode will create the bridging header from objective-c to Swift but this is crucial for making it work the other way around too - apparently.

For the last piece in this puzzle thanks to Swiftoverload for making me aware of actually adding a Swift file via Xcode GUI and not just dragging and dropping existing swift-files into my project for making it work: http://nikolakirev.com/blog/using-swift-in-objective-c-project

JerryZhou
  • 4,566
  • 3
  • 37
  • 60
holm50
  • 821
  • 8
  • 7
16

Using Xcode 8.2.1 and if you look at Project > Build Settings > Objective-C Generated Interface Header Name, there it shows only one header file named like Product-Swift.h

This means that instead of importing each modules separately from Objective-C .m file, using individual -Swift.h file, you just import one Product-Swift.h which aggregated all Swift modules.

I encountered the same problem by looking for traditional way of importing modules separately, but the current version of Xcode and Swift 3 changed it to use only one header for all module importing.

petershine
  • 3,190
  • 1
  • 25
  • 49
  • hi peter, where can you find this file? Or is it autogenerated by xcode? Also, do you have to setup your podfile differently because of this change? – Rob Norback Jan 31 '17 at 03:07
  • @RobNorback If I'm not wrong, you can just write 'import "Product-Swift.h" in Obj-C header/implementation file to see the effect, without doing anything extra. Make sure your project settings have every configuration enabled for Swift and Obj-C mixing. Also, I still haven't experienced an issue with Podfile. Please let me know if I'm seeing things differently. – petershine Feb 01 '17 at 00:34
  • Thank you, I had spent hours trying to debug this, and the problem indeed was that each of the modules in my project was generating their own `-Swift.h` header file. Forcing them all (I have 5 targets) to the use a common header file fixed the issue for me. – Apoorv Khatreja Oct 11 '17 at 18:32
  • @ApoorvKhatreja how did you force them to do that? Wrote the file name explicitly? – Amit Raz Jan 02 '18 at 09:36
13

Spent an hour on this issue, following these steps will help you to understand what's missing:

  1. Open Xcode preference and navigate to DerivedData folder
  2. Search for "swift.h" in finder
  3. If you can not find any project-swift.h file, this file haven't been generated. You usually need to add @objc to one of your swift class and successfully build the app, only then will Xcode generate this file
  4. If you found "xxx-swift.h" file, make sure your import statement contains the correct name.

how-to-locate-swift-file

Jakehao
  • 1,019
  • 8
  • 15
  • Please don't add the [same answer to multiple questions](http://meta.stackexchange.com/questions/104227/is-it-acceptable-to-add-a-duplicate-answer-to-several-questions). Answer the best one and flag the rest as duplicates, once you earn enough reputation. If it is not a duplicate, tailor the post to the question and flag for undeletion. – Bhargav Rao Feb 16 '19 at 02:42
  • Thank you for this! I changed my app's diplay name (not the target's) and the Swift header changed name as well. This was the only way I could find what was going on. – Lucas P. Oct 05 '19 at 16:02
  • Thanks for posting an answer. Screenshots and precise point form immediately make me scroll back + looked + ended my search... problem solved ! – dklt Mar 12 '20 at 05:04
7

iOS - Swift.h file not found

[Mixing Objective-C and Swift]

<name>-Swift.h should be created by Xcode automatically if Swift code expose an API via @objc or @objcMembers[About]

Usually a location looks like

~/Library/Developer/Xcode/DerivedData/
  ProductModuleName-foo/
    Build/
      Intermediates.noindex/
        ProductModuleName.build/
          Debug-iphoneos/
            ProductModuleName.build/
              DerivedSources/
                ProductModuleName-Swift.h

It can be changed by

Project editor -> select a target -> Build Settings -> Per-configuration Intermediate Build Files Path

By default the value is $(PROJECT_TEMP_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)

yoAlex5
  • 29,217
  • 8
  • 193
  • 205
6

I was having problems importing Swift into an Objective-C project. In the end I looked into the Derivied Data folder to check what Xcode 7 was generating. The filename was completely different to the one I was expecting.

Once I had the actual filename I imported that and the project could build.

Joel B
  • 736
  • 7
  • 11
3

If Your App name have any special character then use _ for special character.

For Example if your App name is Name "Test App®"

Then you can import swift file by "Test_App_-Swift.h".

Space and ® is replace by _ while you are import.

Jignesh Mayani
  • 6,937
  • 1
  • 20
  • 36
  • Saved my day, thank you very much! Guys, "special characters" are not only spaces, but this symbol `-` as well. A lot of us create iOS projects and we use `-` as a words separator, so it's an important information – Eugene Alexeev Jul 06 '23 at 08:56
2

Importing the header file, i.e.

#import "<ProjectName>-Swift.h" 

within the .h file generated an error, stating:

-Swift.h' file not found

and the build failed.

Instead use:

#import "<ProjectName>-Swift.h"

within the .m file, and even though the same error appears, running the project anyway suppresses the error.

The swift classes are then available within the .m file.

Stephen Rauch
  • 47,830
  • 31
  • 106
  • 135
Claytog
  • 618
  • 8
  • 8
2

Make sure your swift class has the public declaration, and extends NSObject:

public class MySwiftClass: NSObject {
    //...
}

The import should work with quotes, not brackets, if the swift class is in the same project.

Michael Ribbons
  • 1,753
  • 1
  • 16
  • 26
2

if you add a Swift File first, rememeber to add swift file to your target..., in the left column

JethroYe
  • 31
  • 3
1

Had faced the same problem with my team when was working on project using git. One developer hasn't updated Xcode to the last version (7.3) which was required for latest Swift 2.2 version. So, compiler hasn't recognized new Swift syntax and couldn't generate interface for Swift library (projectname-swift.h). Check if Xcode version is the latest one!

Artem Loginov
  • 801
  • 7
  • 8
  • I my case I faced the problem because had decided to postpone migration to Swift 3 offered by Xcode. As a result Xcode wasn't able to build Swift source files and didn't generate the headers to include. – iutinvg Dec 20 '16 at 12:54
1

DEFINE MODULES: YES and import "ProjectName-Swift.h" in .m file of Obj-C class

This worked for me to access Swift classes in Obj-c.

YSR fan
  • 705
  • 6
  • 11
1

I had the same problem with #import "myProj-Swift.h" not found, Xcode 12.3, the year is 2021.

It appears that unless a bridging header has been generated, it is not possible to import myProj-Swift.h.

My (reproducible) solution, when needing to add Swift to objective-C projects is to create (File - New File - Swift file) a dummy empty Swift file in my project. Xcode then asks whether to create a bridging header, to which I answer yes. This causes a "myProj-Bridging-Header.h" file to be added to my project, which is visible in the Project Navigator.

Once this is done, the error on #import "myProj-Swift.h" disappears.

After that I can delete the dummy file, and insert the needed Swift classes into the project.

The logic of generating a visible bridging header, but leaving the -Swift.h entirely invisible escapes me entirely. Never mind the challenge of trying to find out about this in the official documentation Importing Swift into Objective-C, which (to me inaccurately) states "You don’t need to do anything special to create the generated header".

It is probably a good idea to also mind the answer from @Sandeep Bhandari to this question - who says the -Swift.h file will only be generated if the project compiles successfully.

More info also in this and this question.

Ugo
  • 163
  • 2
  • 9
1

I ran into this problem after duplicating an existing target. When I tried to build with the duplicated target, the "ProductName-Swift.h file not found" error appears.

After going through the build settings in the new target, I found the value of the setting "Product Name" somehow is set as the same as the target name. After setting it with the correct one the error disappeared.

Jason Ou
  • 21
  • 2
1

If your product name is TestApp-Dev then filename will TestApp_Dev-Swift.h

You can verify by going to the following location ~/Library/Developer/Xcode/DerivedData//Build/Intermediates.noindex/yourProjectbuild/Debug-iphonesimulator/MashreqMobileApp.build/DerivedSources

If you want same file name for each build schemes then go to Build Settings to be the same across your modules/schemes. (set it to $(PROJECT_NAME)-Swift.h).

If project name is TestApp, then the file generated will TestApp-Swift.h and it will remain same across the schemes

Amit
  • 2,389
  • 22
  • 29
0

During development, there might be a possibility that you would have any swift class that is not completely implemented due to which there might be some syntax errors. The swift header file will be available for use only if all the swift files are error free.

Make sure there are no syntax errors in the swift files and then try to import the swift header in the objective - c file

Gurunath Sripad
  • 1,308
  • 2
  • 14
  • 24
0

I faced the problem with the name of project (target). It included symbol "-". So the decision was next: if name of project is "Test-App", then name of imported class is "Test_App-Swift.h"

opochtovy
  • 9
  • 2
0

If you have multiple target make sure that you have build all frameworks

Same7Farouk
  • 837
  • 9
  • 19
0

Xcode 11

I ran into this problem when building on Xcode 11. Took me a bit to figure out what was wrong, but essentially, I had changed the "Display Name" setting on the Target's "General" tab instead of changing directly in the Info.plist file through the "Info" tab on the Target.

This resulted in Xcode 11.5 going through an rewriting/creating a bunch of brand new custom build settings and modifying the name of the app module and the built .app product. In this case the new display name also had a forward slash (/) character in it which may ultimately be why it wasn't building (see @Silversky Technology's answer).

Regardless, I resolved this by undoing all of Xcode 11.5's automatic changes to the project file and manually making the same change to the bundle display name in the Info.plist file and everything works perfectly.

I wish it would tell you that it was doing stuff like this before it just up and does it without your consent.

Beltalowda
  • 4,558
  • 2
  • 25
  • 33
0

Target executable was missing a dependency on my (or any other in fact) framework.

Build Phases -> Dependencies must list the dependencies of a target to avoid intermittent errors: in my case debug build was fine and automated Jenkins CI builds were failing. A nightmare to debug considering Jenkins output produces voluminous garbage that's a huge time pit to get through.

Anton Tropashko
  • 5,486
  • 5
  • 41
  • 66