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