iosobjective-cswiftprivateios-frameworks

How to hide private module of iOS Framework?


I have a code-base which consists of Swift top-layer which is meant to be public API and Objective-C "guts" and I need to wrap it up nicely into the iOS .framework so other developers can incorporate my solution without stealing Intellectual Property.

As I know, I need to use Modules system in order to make Obj-C and Swift work together.

So what I did:

1) I created module.modulemap

2) I created module.private.modulemap

3) I set DEFINES_MODULE to YES

4) I set Swift's Import Paths to the Framework folder where both modulemaps are located.

Here's how my module.modulemap looks like:

framework module CoolSDK {
  umbrella header "/full/path/to/file/MyUmbrella.h"

  export *
  module * { export * }
}

Here's how my module.private.modulemap looks like:

module CoolSDK_Private [extern_c] {
      header "/full/path/to/file/ObjC-Guts.h"

      export *
}

I have multiple questions:

1) Why do I need to set the full path to files in modules? When I try to set just the name like so header "file.h" I'm getting an error that file can not be found. I'm positive that files that I try to include lie within modules. Is there some kind of parameter I can set in Build settings?

2) As I said above, my plan is to build a framework with Obj-C guts and Swift top layer, and hence I do not really need an umbrella header, I just need to define a private module so Swift part can have an access to Obj-C part (kind of the same way we do it with Bridging-Header but when it comes to frameworks it's not an option). What should I do in this situation? If I delete module.modulemap completely, XCode generates it's own module.modulemap which looks like this:

module CoolSDK.Swift {
    header "CoolSDK-Swift.h"
    requires objc
}

And of course I have an error that CoolSDK-Swift.h can not be found, so I believe it's not an option. Should I include my Swift public API file as an umbrella header?

3) Although my framework is built successfully and there's no module.private.modulemap inside Modules folder of framework which is exactly what I need (to hide any sign of Obj-C guts via private module), I'm still able to access private module in my SDK tests like so import CoolSDK.Private. How can I make this module exceptional for framework scope and not allow user to get an access to my private module?


Solution

  • Just so you know, I dropped an idea of mixing Swift and Objective-C code base inside the framework. I converted all my Swift parts to Objective-C and after that I was able to apply different practices for hiding private code.