Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Public and Private umbrella header in Objective C

I have this code base which is Objective C and Swift mix. Some places Swift uses Objective and and vice versa. I need to create a framework now based of off this codebase but do not want to include all the objective c files in my umbrella header. Here's my problem:

Inside my framework I still need to be able to use swift from objc and vice versa; but do not want to expose all those objc files that are being used internally by swift classes. Bridging header is not allowed in frameworks so all the headers needed by swift need to go in umbrella header.

I'm wondering if it's possible to have all the objc headers needed by internal swift code go in a file which would be my private umbrella header and all the files that I need to expose would go in public umbrella header.

Any suggestions?

like image 462
puru020 Avatar asked Nov 17 '15 02:11

puru020


Video Answer


1 Answers

I am successfully using explicitly declared modules as a solution of sorts for this issue for the Objective-C -> Swift case. I have not separated the module declaration into a separate private module map but declared both the framework module and an explicit module inside the same modulemap because of the concern raised in one of the comments to the question (I wasn't sure if or how it is possible to use the header generated by the private module map inside the same framework).

Here's an excerpt of the modulemap I have defined for my MPFoundation.framework, which includes an explicit module MPManuscriptCompiler_Protected that imports the header "MPManuscriptCompiler+Protected.h" which is not included in the umbrella header for the framework:

framework module MPFoundation {
    umbrella header "MPFoundation.h"

    export *
    module * { export * }

    explicit module MPManuscriptCompiler_Protected {
        header "MPManuscriptCompiler+Protected.h"
        export *
    }
}

I then use this explicit module MPManuscriptCompiler_Protected in my Swift subclass which is present in the same framework like so:

import MPFoundation.MPManuscriptCompiler_Protected

My solution is really technically just a workaround though: for this to work, "MPManuscriptCompiler+Protected.h" can be marked a private or project level header in the framework, so it will not be visible in the umbrella header and will not be available for header based imports with its filename. So, this works around having to include this header in the umbrella header.

However, the module created this way is publicly exposed in the framework and available for eyes that should not see it. I did not investigate this further as practically this solves the issue well enough (am yet to hit issues where I would have by accident imported that protected header where it wasn't supposed to be imported).

like image 150
mz2 Avatar answered Sep 21 '22 12:09

mz2