Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import private framework headers in a Swift framework?

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?

like image 215
Mihai Damian Avatar asked Feb 26 '15 15:02

Mihai Damian


People also ask

How import OBJC framework in 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.

How do I import a framework?

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".

What is umbrella header?

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.


2 Answers

You need to modify framework A, So that it export a private module.

  1. 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 * } 
  2. In the "Build Settings" of framework A target, search "Private Module Map File" line, and make that:

    $(SRCROOT)/A/private.modulemap 
  3. Do not include private.modulemap file in "Compile Sources". That causes unnecessary warnings.

  4. Clean and Build framework A target.

  5. In framework B Swift files. you can import the private module like this:

    import A import A.Private 
like image 181
rintaro Avatar answered Sep 22 '22 16:09

rintaro


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

like image 20
Andrzej Michnia Avatar answered Sep 22 '22 16:09

Andrzej Michnia