I have a mixed Swift and Objective-C project. To access a Swift public API in Objective-C, the API consumer currently has to import "MyModule-Swift.h". I already have a Objective-C umbrella header called "MyModule.h". But, importing "MyModule.h" is not going to work for the Swift APIs. I tried importing "MyModule-Swift.h" in the umbrella header, but it doesn't find it (I'm assuming since it is generated on the fly by Xcode).
Any suggestions so that an API consumer can always import "MyModule.h" to use public APIs written in Swift/Objective-C will be really appreciated.
====================================================================
Edit: I apologize for not taking the time to properly frame the question. I have a framework called MyModule
.
I have a Objective-C class called ABUser
,
@interface ABUser: NSObject
- (void)walk;
@end
I wanted to add new behavior to this class using Swift, so I defined an extension
extension ABUser {
func swiftWalk()
}
Now, say I wanted to access the swiftWalk
method defined on ABUser
from an Objective-C app, I would have to #import <MyModule/MyModule-Swift.h>
. #import <MyModule/MyModule.h>
would work if I wanted to use the walk
method. This is assuming the umbrella header MyModule.h
imports ABUser.h
.
I always wanted the Objective-C app to #import <MyModule/MyModule.h>
and never have to worry about whether an API was written in Objective-C or Swift in the framework. So, I tried importing MyModule-Swift.h
in the umbrella header MyModule.h
. But, my Objective-C app didn't compile if do that. Not sure, if this is because MyModule-Swift.h
is generated by Xcode on the fly during the build process.
Edit 2: Added a sample project to reproduce this issue here: https://github.com/priteshshah1983/MyObjectiveCApp
The relevant code is in ViewController.m
. The build will fail with the master
branch. To get it work, checkout the working
branch.
The umbrella header is the 'master' header file for a framework. Its use is that you can write #import <UIKit/UIKit.h> instead of #import <UIKit/UIViewController.h> #import <UIKit/UILabel.h> #import <UIKit/UIButton.h> #import <UIKit/UIDatePicker.h> and so on.
Alternatively, you can create a bridging header yourself by choosing File > New > File > [operating system] > Source > Header File. Edit the bridging header to expose your Objective-C code to your Swift code: In your Objective-C bridging header, import every Objective-C header you want to expose to Swift.
The correct approach is as follows: Import your Objective C framework by dragging and dropping the framework into an Xcode 6 Swift project. Create a new Objective C file in your project (File->New->File [Objective C for iOS]). Accept the prompt (agree) to create a bridging header file between Objective C and Swift.
The reason that using @import MyModule;
worked, is that "modules are a packaging together of the framework executable and it's headers" (from this SO post).
In other words, when you @import MyModule;
, Objective-C automatically imports all the swift and Objective-C headers related to the module, while you cannot include the swift header from the umbrella header. I suggest you take a look at the differences between @import
and #import
in the linked SO answer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With