I have an Objective-C framework (framework A) that exposes some public and some private headers. The public headers are also declared in the framework's umbrella header. I have a second Swift framework (framework B) that links with the Objective-C framework.
Now, if I want to import the public headers of A in B I simply need to do an import A
.
But how do I go about importing the private headers?
I know a bridging header is not an option since that's not supported for frameworks. Do I need to somehow create a separate umbrella header for the private headers?
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.
To embed your frameworks, you shouldn't use the build settings directly, but go to the General tab of the project editor for your app target (select the project item in the navigator, then select the target in the editor pane, then select the General tab). Add your framework under "Embedded Binaries".
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.
You need to modify framework A
, So that it export a private module.
Create a private module map file in A
project. This would be something like this:
A/private.modulemap:
explicit module A.Private { // Here is the list of your private headers. header "Private1.h" header "Private2.h" export * }
In the "Build Settings" of framework A
target, search "Private Module Map File" line, and make that:
$(SRCROOT)/A/private.modulemap
Do not include private.modulemap
file in "Compile Sources". That causes unnecessary warnings.
Clean and Build framework A
target.
In framework B Swift files. you can import the private module like this:
import A import A.Private
It is some time since this question was posted. The accepted answer is very good, and as far as I'm concerned it is a common approach.
The problem is, it is not really "private". You can do this inside your framework to access the "private" part:
// Framework A Swift file import A.Private
But If you use framework A in an app (or you ship it to your client), he can still do:
// Client App Swift file import A import A.Private // access "private" framework methods and classes
I was trying to resolve that, as I had recently a situation when I needed to hide it from users (closed source framework) - I just could not let anyone access it, as it was a threat to SDK integrity.
I found a solution to that problem, but a bit too complex to paste it here as a whole.
I made a post about it no medium. Maybe it will help someone checking that problem, that's the link to my article:
https://medium.com/@amichnia_31596/creating-swift-framework-with-private-objective-c-members-the-good-the-bad-and-the-ugly-4d726386644b
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