10

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.

pshah
  • 1,954
  • 1
  • 19
  • 39

2 Answers2

2

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.

Community
  • 1
  • 1
vigneshv
  • 593
  • 7
  • 17
-1

It turns out that using @import MyModule; instead of #import <MyModule/Module.h> allows using walk and swiftWalk methods as expected from the Objective-C app.

I honestly don't understand the details, but I hope this helps someone else. Please feel free to explain!

pshah
  • 1,954
  • 1
  • 19
  • 39
  • "Please feel free to explain" What's my motivation? You've awarded yourself the correct answer, so the bounty is unwinnable. You've thrown away 50 points for nothing, too... And the question is still pretty rotten. What does "But, this didn't work" even _mean_? – matt Oct 16 '15 at 00:32
  • Ok, I retracted my answer as the correct answer. Sorry, I don't think I can explain it better than this though. I noticed you've already down voted me for that! – pshah Oct 16 '15 at 00:51
  • What can't you just show all of the actual code needed for someone to understand and reproduce the problem? – matt Oct 16 '15 at 01:03
  • Added a sample project to reproduce this issue here: https://github.com/priteshshah1983/MyObjectiveCApp – pshah Oct 16 '15 at 04:10