For references in this issue, you can look at ZSWTaggedString (branch zac-swift-modulemap) to see what I'm talking about.
In my project, the generated .modulemap looks like so:
framework module ZSWTaggedString {
umbrella header "ZSWTaggedString-umbrella.h"
export *
module * { export * }
private header "ZSWStringParser.h"
private header "ZSWStringParserTag.h"
private header "ZSWTaggedStringAttribute.h"
}
However, these private headers are inaccessible in the Swift version of my framework. As far as I can tell, I'm doing things correctly here, but this is an area of Xcode/clang that has so little documentation I could vomit.
Apple's documentation suggests that I should create a ZSWTaggedString.private.modulemap for this situation (where I want to expose some private headers internal to my framework), and Xcode has a build setting MODULEMAP_PRIVATE_FILE to do so.
I can assign a value to this flag using a pod xcconfig like ${PODS_ROOT}/ZSWTaggedString/ZSWTaggedString.private.modulemap, but the directory it's referencing won't exist because it's not copied in for a development pod. Secondarily, this seems fragile as CocoaPods has changed directory structures in unexpected ways in the past.
I think, like providing my own spec.module_map which is copied into my Target Support Files directory, I should be able to provide a private_module_map which has the same behavior.
Alternatively, a *.private.modulemap could be generated automatically much like the normal modulemap, containing all references to the private headers I've defined in my podspec.
Seems reasonable to me, although the private header bit should be gone now since it broke things ¯_(ツ)_/¯
I'd be open to a PR adding this functionality, but its not going to be a high priority for the time being.
I've given this a few (quite a few, actually) more hours of work, and I've drawn a few conclusions:
.modulemapI don't think there's anything Cocoapods can do to improve this situation, so I'm closing this issue.
Thanks for taking the time to investigate, @zacwest !
Has any progress been done in that?
We currently are hitting this problem.
@segiddins Did you get anywhere with this?
We have an framework which is written in Obj-C we are now adding in some private swift files into the framework which need to import some of the existing private Obj-C files. Currently the only way we are able to do this is by making the Obj-C files public.
@bencallis you can use a custom module map -- reading through the issue, it seems the conclusion was there's nothing for CocoaPods to do here?
@segiddins do you have any instructions on how to do this?
To be a bit clearer. We have FileA, FileB, FileC all inside the same framework.
FileA is in ObjC and a public file in the framework.
FileB is in ObjC and a private file in the framework.
FileC is in Swift and is a private file in the framework. FileC can access FileA but not FileB.
Making FileB public solves the issue but is not ideal.
I do not believe it is possible to expose private .h files to Swift inside a framework.
I ended up using a custom modulemap with a module called "Private" in the hopes consumers wouldn't use it. See here: https://github.com/zacwest/ZSWTaggedString/blob/master/ZSWTaggedString/Classes/ZSWTaggedString.modulemap
@zacwest sounds like a good solution. Will look into trying this :) Thanks.
@zacwest I am also trying to share private ObjectiveC files to my Swift framework and trying to hide them from outer world: https://stackoverflow.com/questions/56769304/extending-a-public-class-for-partial-public-access-in-swift
I tried your solution and it did not work. Here is how my modulemap looks like:
framework module MySDK {
umbrella header "MySDK-umbrella.h"
export *
module * { export * }
explicit module Private {
header "CardDetails.h"
}
}
Please take a look at my stackoverflow question.
Most helpful comment
I do not believe it is possible to expose private .h files to Swift inside a framework.
I ended up using a custom modulemap with a module called "Private" in the hopes consumers wouldn't use it. See here: https://github.com/zacwest/ZSWTaggedString/blob/master/ZSWTaggedString/Classes/ZSWTaggedString.modulemap