Can't use Swift classes inside Objective-C - ios

I try to integrate Swift code in my app.My app is written in Objective-C and I added a Swift class. I've done everything described here. But my problem is that Xcode haven't created the -Swift.h file, only the bridging headers. So I created it, but it's actually empty.
I can use all my ObjC classes in Swift, but I can't do it vice versa. I marked my swift class with #objc but it didn't help. What can I do now?
EDIT: Apple says:" When you import Swift code into Objective-C, you rely on an Xcode-generated header file to expose those files to Objective-C. [...] The name of this header is your product module name followed by adding “-Swift.h”. "
Now when I want to import that File, it gives an error:
//MainMenu.m
#import "myProjectModule-Swift.h" //Error: 'myProjectModule-Swift.h' file not found
#implementation MainMenu
Here is my FBManager.swift file:
#objc class FBManager: NSObject {
var descr = "FBManager class"
init() {
super.init()
}
func desc(){
println(descr)
}
func getSharedGameState() -> GameState{
return GameState.sharedGameState() //OK! GameState is written in Objective-C and no error here
}
}

I spent about 4 hours trying to enable Swift in my Xcode Objective-C based project. My myproject-Swift.h file was created successfully, but my Xcode didn't see my Swift-classes. So, I decided to create a new Xcode Objc-based project and finally, I found the right answer! Hope this post will help someone :-)
Step by step Swift integration for Xcode Objc-based project:
Create new *.swift file (in Xcode) or add it by using Finder.
Create an Objective-C bridging header when Xcode asks you about that.
Implement your Swift class:
import Foundation
// use #objc or #objcMembers annotation if necessary
class Foo {
//..
}
Open Build Settings and check these parameters:
Defines Module : YES
Copy & Paste parameter name in a search bar
Product Module Name : myproject
Make sure that your Product Module Name doesn't contain any special characters
Install Objective-C Compatibility Header : YES
Once you've added *.swift file to the project this property will appear in Build Settings
Objective-C Generated Interface Header : myproject-Swift.h
This header is auto-generated by Xcode
Objective-C Bridging Header : $(SRCROOT)/myproject-Bridging-Header.h
Import Swift interface header in your *.m file.
#import "myproject-Swift.h"
Don't pay attention to errors and warnings.
Clean and rebuild your Xcode project.
Profit!

Don't create the header file yourself. Delete the one you created.
Make sure your Swift classes are tagged with #objc or inherit from a class that derives (directly or indirectly) from NSObject.
Xcode won't generate the file if you have any compiler errors in your project - make sure your project builds cleanly.

Allow Xcode to do its work, do not add/create Swift header manually. Just add #objc before your Swift class ex.
#objc class YourSwiftClassName: UIViewController
In your project setting search for below flags and change it to YES (Both Project and Target)
Defines Module : YES
Always Embed Swift Standard Libraries : YES
Install Objective-C Compatibility Header : YES
Then clean the project and build once, after build succeed (it should probably) import below header file in your objective-c class .m file
#import "YourProjectName-Swift.h"
Boooom!

Also probably helpful for those of you with a Framework target:
The import statement of the auto-generated header file looks a bit different from app targets. In addition to the other things mentioned in other answers use
#import <ProductName/ProductModuleName-Swift.h>
instead of
#import "ProductModuleName-Swift.h"
as per Apples documentation on Mix & Match for framework targets.

Details: Objective-C project with Swift 3 code in Xcode 8.1
Tasks:
Use swift enum in objective-c class
Use objective-c enum in swift class
FULL SAMPLE
1. Objective-C class which use Swift enum
ObjcClass.h
#import <Foundation/Foundation.h>
typedef NS_ENUM(NSInteger, ObjcEnum) {
ObjcEnumValue1,
ObjcEnumValue2,
ObjcEnumValue3
};
#interface ObjcClass : NSObject
+ (void) PrintEnumValues;
#end
ObjcClass.m
#import "ObjcClass.h"
#import "SwiftCode.h"
#implementation ObjcClass
+ (void) PrintEnumValues {
[self PrintEnumValue:SwiftEnumValue1];
[self PrintEnumValue:SwiftEnumValue2];
[self PrintEnumValue:SwiftEnumValue3];
}
+ (void) PrintEnumValue:(SwiftEnum) value {
switch (value) {
case SwiftEnumValue1:
NSLog(#"-- SwiftEnum: SwiftEnumValue1");
break;
case SwiftEnumValue2:
case SwiftEnumValue3:
NSLog(#"-- SwiftEnum: long value = %ld", (long)value);
break;
}
}
#end
Detect Swift code in Objective-C code
In my sample I use SwiftCode.h to detect Swift code in Objective-C. This file generate automatically (I did not create a physical copy of this header file in a project), and you can only set name of this file:
If the compiler can not find your header file Swift code, try to compile the project.
2. Swift class which use Objective-C enum
import Foundation
#objc
enum SwiftEnum: Int {
case Value1, Value2, Value3
}
#objc
class SwiftClass: NSObject {
class func PrintEnumValues() {
PrintEnumValue(.Value1)
PrintEnumValue(.Value2)
PrintEnumValue(.Value3)
}
class func PrintEnumValue(value: ObjcEnum) {
switch value {
case .Value1, .Value2:
NSLog("-- ObjcEnum: int value = \(value.rawValue)")
case .Value3:
NSLog("-- ObjcEnum: Value3")
break
}
}
}
Detect Objective-C code in Swift code
You need to create bridging header file. When you add Swift file in Objective-C project, or Objective-C file in swift project Xcode will suggest you to create bridging header.
You can change bridging header file name here:
Bridging-Header.h
#import "ObjcClass.h"
Usage
#import "SwiftCode.h"
...
[ObjcClass PrintEnumValues];
[SwiftClass PrintEnumValues];
[SwiftClass PrintEnumValue:ObjcEnumValue3];
Result
MORE SAMPLES
Full integration steps Objective-c and Swift described above. Now I will write some other code examples.
3. Call Swift class from Objective-c code
Swift class
import Foundation
#objc
class SwiftClass:NSObject {
private var _stringValue: String
var stringValue: String {
get {
print("SwiftClass get stringValue")
return _stringValue
}
set {
print("SwiftClass set stringValue = \(newValue)")
_stringValue = newValue
}
}
init (stringValue: String) {
print("SwiftClass init(String)")
_stringValue = stringValue
}
func printValue() {
print("SwiftClass printValue()")
print("stringValue = \(_stringValue)")
}
}
Objective-C code (calling code)
SwiftClass *obj = [[SwiftClass alloc] initWithStringValue: #"Hello World!"];
[obj printValue];
NSString * str = obj.stringValue;
obj.stringValue = #"HeLLo wOrLd!!!";
Result
4. Call Objective-c class from Swift code
Objective-C class (ObjcClass.h)
#import <Foundation/Foundation.h>
#interface ObjcClass : NSObject
#property NSString* stringValue;
- (instancetype) initWithStringValue:(NSString*)stringValue;
- (void) printValue;
#end
ObjcClass.m
#import "ObjcClass.h"
#interface ObjcClass()
#property NSString* strValue;
#end
#implementation ObjcClass
- (instancetype) initWithStringValue:(NSString*)stringValue {
NSLog(#"ObjcClass initWithStringValue");
_strValue = stringValue;
return self;
}
- (void) printValue {
NSLog(#"ObjcClass printValue");
NSLog(#"stringValue = %#", _strValue);
}
- (NSString*) stringValue {
NSLog(#"ObjcClass get stringValue");
return _strValue;
}
- (void) setStringValue:(NSString*)newValue {
NSLog(#"ObjcClass set stringValue = %#", newValue);
_strValue = newValue;
}
#end
Swift code (calling code)
if let obj = ObjcClass(stringValue: "Hello World!") {
obj.printValue()
let str = obj.stringValue;
obj.stringValue = "HeLLo wOrLd!!!";
}
Result
5. Use Swift extension in Objective-c code
Swift extension
extension UIView {
static func swiftExtensionFunc() {
NSLog("UIView swiftExtensionFunc")
}
}
Objective-C code (calling code)
[UIView swiftExtensionFunc];
6. Use Objective-c extension in swift code
Objective-C extension (UIViewExtension.h)
#import <UIKit/UIKit.h>
#interface UIView (ObjcAdditions)
+ (void)objcExtensionFunc;
#end
UIViewExtension.m
#implementation UIView (ObjcAdditions)
+ (void)objcExtensionFunc {
NSLog(#"UIView objcExtensionFunc");
}
#end
Swift code (calling code)
UIView.objcExtensionFunc()

Make sure your project defines a module and you have given a name to the module. Then rebuild, and Xcode will create the -Swift.h header file and you will be able to import.
You can set module definition and module name in your project settings.

I had the same issue and it turned out special symbols in the module name are replaced by xcode (in my case dashes ended up being underscores). In project settings check "module name" to find the module name for your project. After that either use ModuleName-Swift.h or rename the module in settings.

The file is created automatically (talking about Xcode 6.3.2 here). But you won't see it, since it's in your Derived Data folder. After marking your swift class with #objc, compile, then search for Swift.h in your Derived Data folder. You should find the Swift header there.
I had the problem, that Xcode renamed my my-Project-Swift.h to my_Project-Swift.h Xcode doesn't like
"." "-" etc. symbols. With the method above you can find the filename and import it to a Objective-C class.

For Swift 5:
Add the #objc keyword to your class and methods
Add public keyword to your class and methods
Let your class inherit from NSObject
Build Project
Put #import "MyProject-Swift.h" in your Objective-C file
#objc
public class MyClass: NSObject {
#objc
public func myMethod() {
}
}

Just include
#import "myProject-Swift.h" in .m or .h file
P.S You will not find "myProject-Swift.h" in file inspector it's hidden. But it is generated by app automatically.

#sig answer is one of the best, however, it did not work for me with the old project (not new!), I needed some modifications. After a lot of variations I found the recipe for me (using XCode 7.2):
Product Module Name : $(PRODUCT_NAME:c99extidentifier)
Defines Module : NO
Embedded Content Contains Swift : NO
Install Objective-C Compatibility Header : YES
Objective-C Bridging Header : ProjectName-Bridging-Header.h
The last point (5) was crucial. I put it only on the second section (Targets field), the Project field should be left empty: Otherwise, it did not generate the right "Project-Swift.h" file for me (it did not include swift methods).

There is two condition,
Use your swift file in objective c file.
Use your objective c file in swift file.
So, For that purpose, you have to follow this steps:
Add your swift file in an objective-c project or vice-versa.
Create header(.h) file.
Go to Build Settings and perform below steps with search,
search for this text "brid" and set a path of your header file.
"Defines Module": YES.
"Always Embed Swift Standard Libraries" : YES.
"Install Objective-C Compatibility Header" : YES.
After that, clean and rebuild your project.
Use your swift file in objective c file.
In that case,First write "#objc" before your class in swift file.
After that ,In your objective c file, write this,
#import "YourProjectName-Swift.h"
Use your objective c file in swift file.
In that case, In your header file, write this,
#import "YourObjective-c_FileName.h"
I hope this will help you.

In my case, apart from these steps:
Product Module Name : myproject
Defines Module : YES
Embedded Content Contains Swift : YES
Install Objective-C Compatibility Header : YES
Objective-C Bridging Header : $(SRCROOT)/Sources/SwiftBridging.h
I have needed to put the class as public in order to create productName-Swift.h file:
import UIKit
#objc public class TestSwift: NSObject {
func sayHello() {
print("Hi there!")
}
}

I just discovered that adding a directory of swift files to a project won't work. You need to create a group first for the directory, then add the swift files...

I had the same problem and finally it appeared that they weren't attached to the same targets.
The ObjC class is attached to Target1 and Target2, the Swift class is only attached to the Target1 and is not visible inside the ObjC class.
Hope this helps someone.

my problem was I got stuck after xcode created the bridge file but still I got error in header file name MYPROJECTNAME-swift.h
1.I check in terminal and search for all auto created swift bridge files:
find ~/library/Developer/Xcode/DerivedData/ -name "*-Swift.h"|xargs basename|sort -
you see what xcode created.
in my case, I had space in my project name and xcode replace this is '_'

When you add new Swift files to the project, please, make sure that you add them to correct targets.
Please, make sure that every swift file you're going to use inherits NSObject class and annotated with #ObjCMembers
Change to YES inside the build settings under the option ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES.
Change to YES inside the build settings under the option DEFINES_MODULE.

Using Swift Classes in Objective-C
If you are going to import code within an App Target (Mixing Objective-C and Swift in one project) you should use the next import line #import "<#YourProjectName#>-Swift.h" to expose Swift code to Objective-C code [Mixing Swift and Objective-C code in a project]
In this post I will describe how to import Swift static library to Objective-C code
Objective-C consumer -> Swift static library
Xcode version 10.2.1
Create Swift static library
Follow Create Swift static library with next additions:
Expose Swift API. To use Swift's functions from Objective-C[About]
After building you should find a <product_name>-Swift.h file that should be located into DerivedSources [File not found]
Objective-C consumer with Swift static library
Drag and drop the binary into the Xcode project[About]
Link Library[Undefined symbols] [Link vs Embed]
Project editor -> select a target -> General -> Linked Frameworks and Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file
//or
Project editor -> select a target -> Build Phases -> Link Binary With Libraries -> add -> Add Others... -> point to `lib<product_name>.a` file
Add Library Search paths[Library not found for] [Recursive path]
Project editor -> select a target -> Build Settings -> Search Paths -> Library Search paths -> add path to the parent of `lib<product_name>.a` file
Add Header Search Paths[Module not found] [Recursive path]
Project editor -> select a target -> Build Settings -> Search Paths -> Header Search Paths -> add path to generated `<product_name>-Swift.h` file
Add empty .swift file to the Objective-C project.[Undefined symbols] When Xcode ask press Create Bridging Header(it will create module_name-Bridging-Header.h) and setup a path to this file in
Project editor -> select a target -> Build Settings -> Swift Compiler - General -> Objective-C Bridging Header
Import module to the Objective-C client code[File not found] [module_name]
#import "module_name-Swift.h"
More examples here

I have the same error: myProjectModule-Swift.h file not found", but, in my case, real reason was in wrong deployment target:
"Swift is unavailable on OS X earlier than 10.9; please set MACOSX_DEPLOYMENT_TARGET to 10.9 or later (currently it is '10.7')"
so, when I've changed deployment target to 10.9 - project had been compiled successfully.

My issue was that the auto-generation of the -swift.h file was not able to understand a subclass of CustomDebugStringConvertible. I changed class to be a subclass of NSObject instead. After that, the -swift.h file now included the class properly.

I had issues in that I would add classes to my objective-c bridging header, and in those objective-c headers that were imported, they were trying to import the swift header. It didn't like that.
So in all my objective-c classes that use swift, but are also bridged, the key was to make sure that you use forward class declarations in the headers, then import the "*-Swift.h" file in the .m file.

I didnt have to change any settings in the build or add #obj to the class.
All I had to do was to create bridge-header which was automatically created when I created Swift classes into Objective-c project. And then I just had to do
import "Bedtime-Swift.h" <- inside objective-c file that needed to use that swift file.

well, after reading all the comments and trying and reading and trying again, I managed to include swift classes into my Big obj-c project.
So, thanks for all the help.
I wanted to share one tip that helped me understand the process better.
In the .m class, went to the import line of the swift target name #import "myTargetName-Swift.h"
and clicked the key:
command + mouse click -> Jump to definition
There you can see all the translation from swift to obj-c and ther you will find the various functions re-declared in obj-c.
Hope this tip will help you as much as it helped me.

XCode 11.3.1:
When I want to use an Swift inner class in a objc code, it does not compile for ther error "undefined symbol"(for bother inner class and outer class), I checked the generated "-swift.h" header and both classes are there.
After trying for hours I convert the inner class to a normal class and it compiles.
I clean the project, delete the DerivedData folder and it compiles.

I use CocoaPods and the Swift class from my library couldn't be located from the Objective-C code in the example app because it's project and target were named the same as the library, so I had to remove the Objective-C Generated Interface Name values so they didn't conflict with the ones from the library.

Archiving will be successful already tested
How to call a swift function (that could be in a swift framework also) in objective c project or react native project
it will work for react-native also
follow these steps :
Open Build Settings and check these parameters:
Defines Module : YES
in AppDelegate.h
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#class KB;
#interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
#property (strong, nonatomic) KB *appkb;
#end
in AppDelegate.m
#import "AppDelegate.h"
#import "ProductModuleName-Swift.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self.appkb methodReceiveSwiftClass];
[self.appkb methodEvents:event prop:properties];
}
#end
KB.swift
import Foundation
// import framework if using a swift framework in objective c or react native native modules.
#objc public class KB:NSObject{
#objc public func methodReceiveSwiftClass(){
//write anything here....
}
#objc public func methodEvents(_ event: String, prop: String){
//write anything here
//func with params
}
}
ProjectModuleName-Bridging-Header.h
#import "React/RCTBridgeModule.h"
#import "AppDelegate.h"

After doing everything above, I still got errors. My problem ended up being that the Swift files I needed weren't added to the bundle resources for some reason.
I fixed this by going to [MyTarget] > Build Phases > Copy Bundle Resources, then clicked the plus button and added the Swift files.

Related

Receiver '**' for class message is a forward declaration Error. Swift Static Library use in Objective-C

I am trying to make a Swift Static library and apply it to Swift and Objective Project.
import Foundation
#objc open class Library001_Test: NSObject {
public override init(){}
#objc public func testPrint() {
print("My Name is Andi")
}
#objc public func getUUID(userName: String) -> String {
let uuid = UUID().uuidString
return "\(userName)'s UUID : \(uuid)"
}
}
I wrote the code like this using Swift.
And in the Edit Scheme menu, I changed the Build Configuration to Release and proceeded with Run. As a result, the 'libLibrary001.a' file and the 'Library001.swiftmodule' folder were created.
These two artifacts work well when pasted into a Swift project and imported.
But the problem is an Objective-C project.
I put both artifacts into my project and checked:
[General - Frameworks, Libraries. and Embedded Content] whether the library is recognized
Whether the library is recognized in [Build Phases - Link Binary With Libraries]
Check [Build Settings - Library Search Paths] address
Defines Module - Yes
And I put '#class Library001_Test;' in ViewController.h
#import <UIKit/UIKit.h>
#class Library001_Test;
#interface ViewController : UIViewController
#end
And in ViewController.m, '#import "ProductName-Swift.h" and the created Class were loaded.
#import "ViewController.h"
#import "SwiftInObjectiveC-Swift.h"
#interface ViewController ()
#end
#implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
Library001_Test *test = [[Library001_Test alloc] init];
}
#end
error : Receiver 'Library001_Test' for class message is a forward declaration
error : Receiver type 'Library001_Test' for instance message is a forward declaration
An error occurred while doing this. I've tried all the methods I've found on the internet and I'm wondering where the problem is.
Is the code the problem? Did I not set it up well??
The Swift file created in the project is import well in Objective-C... Why the hell is the .a file not working like this?
My problem was with '(ProductName)-Swift.h'
If you look at how Swift Code is used in Objective-C, many articles say to import (ProductName)-Swift.h. So I only added the project header that I want to apply, but I also need to add the product header made from the library.
My problem was simple, but it took me a long time to figure it out. The error was not found 'Class' and 'func' in Swift static library. My workaround was resolved using the (LibraryProductName)-Swift.h of the library I created, rather than the (ProductName)-Swift.h of the project you are working on.
If you refer to the address below, you can prevent the error that occurred in advance.
https://medium.com/#mail2ashislaha/swift-objective-c-interoperability-static-libraries-modulemap-etc-39caa77ce1fc

iOS Swift project, have Objective-C file and I want to import a swift class to the Objective-C file [duplicate]

I have written a library in Swift and I wasn't able to import it to my current project, written in Objective-C.
Are there any ways to import it?
#import "SCLAlertView.swift" - 'SCLAlertView.swift' file not found
You need to import ProductName-Swift.h. Note that it's the product name - the other answers make the mistake of using the class name.
This single file is an autogenerated header that defines Objective-C interfaces for all Swift classes in your project that are either annotated with #objc or inherit from NSObject.
Considerations:
If your product name contains spaces, replace them with underscores (e.g. My Project becomes My_Project-Swift.h)
If your target is a framework, you need to import <ProductName/ProductName-Swift.h>
Make sure your Swift file is member of the target
Here's what to do:
Create a new Project in Objective-C
Create a new .swift file
 
A popup window will appear and ask "Would You like to configure an Objective-C bridging Header".
Choose Yes.
Click on your Xcode Project file
Click on Build Settings
Find the Search bar and search for Defines Module.
Change value to Yes.
Search Product Module Name.
Change the value to the name of your project.
In App delegate, add the following : #import "YourProjectName-Swift.h"
Note: Whenever you want to use your Swift file you must be import following line :
#import "YourProjectName-Swift.h"
Instructions from the Apple website:
To import Swift code into Objective-C from the same framework
Under Build Settings, in Packaging, make sure the Defines Module
setting for that framework target is set to Yes. Import the Swift code
from that framework target into any Objective-C .m file within that
framework target using this syntax and substituting the appropriate
names:
#import "ProductName-Swift.h"
Revision:
You can only import "ProductName-Swift.h" in .m files.
The Swift files in your target will be visible in Objective-C .m files
containing this import statement.
To avoid cyclical references, don’t import Swift into an Objective-C
header file. Instead, you can forward declare a Swift class to use it
in an Objective-C header. Note that you cannot subclass a Swift class
in Objective-C.
If you're using Cocoapods and trying to use a Swift pod in an ObjC project you can simply do the following:
#import <FrameworkName>;
Go to build settings in your project file and search for "Objective-C Generated Interface Header Name. The value of that property is the name that you should include.
If your "Product Module Name" property (the one that the above property depends on by default) varies depending on whether you compile for test/debug/release/etc (like it does in my case), then make this property independent of that variation by setting a custom name.
Importing Swift file inside Objective-c can cause this error, if it doesn't import properly.
NOTE: You don't have to import Swift files externally, you just have to import one file which takes care of swift files.
When you Created/Copied Swift file inside Objective-C project. It would've created a bridging header automatically.
Check Objective-C Generated Interface Header Name at Targets -> Build Settings.
Based on above, I will import KJExpandable-Swift.h as it is.
Your's will be TargetName-Swift.h, Where TargetName differs based on your project name or another target your might have added and running on it.
As below my target is KJExpandable, so it's KJExpandable-Swift.h
First Step:-
Select Project Target -> Build Setting -> Search('Define') -> Define Module
update value No to Yes
"Defines Module": YES.
"Always Embed Swift Standard Libraries" : YES.
"Install Objective-C Compatibility Header" : YES.
Second Step:-
Add Swift file Class in Objective C ".h" File as below
#import <UIKit/UIKit.h>
#class TestViewController(Swift File);
#interface TestViewController(Objective C File) : UIViewController
#end
Import 'ProjectName(Your Project Name)-Swift.h' in Objective C ".m" file
//TestViewController.m
#import "TestViewController.h"
/*import ProjectName-Swift.h file to access Swift file here*/
#import "ProjectName-Swift.h"
If you have a project created in Swift 4 and then added Objective-C files, do it like this:
#objcMembers
public class MyModel: NSObject {
var someFlag = false
func doSomething() {
print("doing something")
}
}
Reference: https://useyourloaf.com/blog/objc-warnings-upgrading-to-swift-4/
There's one caveat if you're importing Swift code into your Objective-C files within the same framework. You have to do it with specifying the framework name and angle brackets:
#import <MyFramework/MyFramework-Swift.h>
MyFramework here is the "Product Module Name" build setting (PRODUCT_NAME = MyFramework).
Simply adding #import "MyFramework-Swift.h" won't work. If you check the built products directory (before such an #import is added, so you've had at least one successful build with some Swift code in the target), then you should still see the file MyFramework-Swift.h in the Headers directory.
Be careful with dashes and underscores, they can be mixed up and your Project Name and Target name won't be the same as SWIFT_MODULE_NAME.
Checkout the pre-release notes about Swift and Objective C in the same project
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-XID_75
You should be importing
#import "SCLAlertView-Swift.h"
Search for "Objective-C Generated Interface Header Name" in the Build Settings of the target you're trying to build (let's say it's MyApp-Swift.h), and import the value of this setting (#import "MyApp-Swift.h") in the source file where you're trying to access your Swift APIs.
The default value for this field is $(SWIFT_MODULE_NAME)-Swift.h. You can see it if you double-click in the value field of the "Objective-C Generated Interface Header Name" setting.
Also, if you have dashes in your module name (let's say it's My-App), then in the $(SWIFT_MODULE_NAME) all dashes will be replaced with underscores. So then you'll have to add #import "My_App-Swift.h".
If you want to use Swift file into Objective-C class, so from Xcode 8 onwards you can follow below steps:
If you have created the project in Objective-C:
Create new Swift file
Xcode will automatically prompt for Bridge-Header file
Generate it
Import "ProjectName-Swift.h" in your Objective-C controller (import in implementation not in interface) (if your project has space in between name so use underscore "Project_Name-Swift.h")
You will be able to access your Objective-C class in Swift.
Compile it and if it will generate linker error like: compiled with newer version of Swift language (3.0) than previous files (2.0) for architecture x86_64 or armv 7
Make one more change in your
Xcode -> Project -> Target -> Build Settings -> Use Legacy Swift Language Version -> Yes
Build and Run.
#import <TargetName-Swift.h>
you will see when you enter from keyboard #import < and after automaticly Xcode will advice to you.
only some tips about syntax, about Xcode everything has been said
you cannot import 'pure" functions, only classes, even if marked "public", so:
public func f1(){
print("f1");
}
will NOT be called in ANY way.
If You write classes., add inheritance from NSObject, other will NOT be usable.
if it inherits from NSObject, as below:
class Utils : NSObject{
static func aaa()->String{
return "AAA"
}
#objc static func bbb()->String{
return "BBB"
}
#objc private static func ccc()->String{
return "CCC"
}
}
in OBJC:
aaa() NOT called: "No known class method for selector 'aaa'"
bbb() ok
ccc() NOT called: "No known class method for selector 'aaa'"
Find the .PCH file inside the project. and then add #import "YourProjectName-Swift.h" This will import the class headers. So that you don't have to import into specific file.
#ifndef __IPHONE_3_0
#warning "This project uses features only available in iPhone SDK 3.0 and later."
#endif
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "YourProjectName-Swift.h"
#endif

I've tried it all, but I can't import my Swift file to my Objective-C file

I've read though multiple threads on this on StackOverflow, and I can't seem to find the answer to my problem. My folder hierarchy is like this:
"Project Name"
- "Helpers"
"FileIWantToImport.swift"
"FileIWantToImportTo.m"
I have:
Set the build settings to have a Product Module Name FMB
Set Defines Modules to YES
a bridging header created by Xcode
cleaned my build
#import FMB-swift.h in my AppDelegate with out any problems
Added #objc to my class declaration in my file so it says #objc class MyClass: NSObject
HOWEVER. I cannot, for the life me, figure out why it won't import into FileIWantToImportTo.m
I have tried:
#import "FMB-swift.h"
#import "Helpers/FMB-swift.h"
#import "Product Name/Helpers/FMB-swift.h"
#import <FMB-swift.h>
#import <Helpers/FMB-swift.h>
#import <Product Name/Helpers/FMB-swift.h>
All I get is "file not found" error. Can someone please point me in the right direction? I've looked through all the other threads and the apple docs and can't figure it out. I'm running in Xcode 7 and 10.11 GMs if that makes a difference.
EDIT: Here is an example project https://github.com/Aghassi/Example-Project
This is what you need to do:
Create a Swift file in your ObjC based project. No need to create bridging headers, since they're used to see ObjC code from swift, not swift code from ObjC.
In your Target, under Build Settings set Embedded Content Contains Swift Code to Yes
Your Swift file should have an #objc public class.
#objc public class Example: NSObject {
public func printSomething(text: String) {
print(text);
}
}
Check your Project's name, and in your .m file, add #import <ProjectsName-Swift.h>, and you should be able to instantiate your class defined in the Swift file, and all it's public methods. You might need to build your project before importing the -Swift.h file.
Here's an example project with an ObjC class using Swift code: https://github.com/lucaslt89/Example-Project.git

How to import swift file into objective-c file in a swift project

The situation is a little complicated. I have a Swift project, and I have imported some Objective-C files into this project. Now, I want to use some Swift classes in these Objective-C files. How to do that?
It seems this reference covers everything:
https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html
Specifically:
Importing Swift into Objective-C
When you import Swift code into Objective-C, you rely on an
Xcode-generated header file to expose those files to Objective-C. This
automatically generated file is an Objective-C header that declares
the Swift interfaces in your target. It can be thought of as an
umbrella header for your Swift code. The name of this header is your
product module name followed by adding "-Swift.h". (You’ll learn more
about the product module name later, in Naming Your Product Module.)
Example:
Foo.swift in product named ExampleProduct
#objc public class Bar: NSObject {
var x: Int = 3
}
Blah.m in same product:
#import <Foundation/Foundation.h>
#import <ExampleProduct-Swift.h>
void doStuff() {
Bar *y = [[Bar alloc] init];
printf("%ld\n", (long)y.x);
}
It's even easy to call doStuff() from a Swift file if you create an Objective-C header file that defines the function prototype and then import that header file in the bridging header.
There's no limit to jumping back and forth.
Based on the comments it looks like you're having trouble importing the reverse bridging header.
Try this in terminal to ensure you're naming the file correctly:
% cd ~/Library/Developer/Xcode; find . -name '*-Swift.h'
I get (scroll all the way to the right):
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProduct.build/DerivedSources/ExampleProduct-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProduct.build/Objects-normal/x86_64/ExampleProduct-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProductTests.build/DerivedSources/ExampleProductTests-Swift.h
./DerivedData/ExampleProduct-avoxifngmebkkqgndldocildsfcm/Build/Intermediates/ExampleProduct.build/Debug-iphonesimulator/ExampleProductTests.build/Objects-normal/x86_64/ExampleProductTests-Swift.h
Also, potentially a dup of:
How to call Objective-C code from Swift
With 326 upvotes that's worth studying!

Umbrella header file not updating after changing any swift code

I have a Mix project of Swift and Objective C. Initially I created a the project choosing Swift as language.
I have Objective C Bridging headers working absolutely fine - as I add any new obj c code that I manually update in Header file.
I imported "ProjectName-Swift.h" file in obj c and It worked fine. Now when I change any code in my swift files or add new swift files I can see "ProjectName-Swift.h" file is not updated with new changes. I tried to manually change the file and it worked.
I cleaned the project and rebuilt but no luck. I deleted the generated "ProjectName-Swift.h" file and tried building but still new changes are not shown.
SWIFT_CLASS("_TtC8MyProject13Type2")
#interface Type2 : NSObject
+ (Type2 *)sharedInstance;
- (float)method1:(Type2 *)entity amount:(float)amount;
- (float)method2:(Type1 *)category amount:(float)amount;
- (instancetype)init OBJC_DESIGNATED_INITIALIZER;
#end
Any solution for this problem?
I know this was a long time ago, but I just struggled with the same problem when adding a protocol to my Swift code, and it wasn't being added to the -Swift.h header file.
The problem was my protocol wasn't marked as Public. I changed my protocol from this:
#objc protocol MyProtocol { //etc.... }
to this:
#objc public protocol MyProtocol { //etc.... }

Resources