C Objective Classes in iOS Swift Dynamic Framework

Situation:

I have a jyan dyanmic framework written in Swift. I also have a bunch of classes written in Objective-C that I would like to use in my Swift classes (some of them are public, some of them are private). However , I would like Objective-C classes not to be exposed to projects using my infrastructure .


What I tried:

Umbrella header

From what I understand, I have to import using #import header.h into my umbrella header file, which is usually FrameworkName.h , and then make sure that all Objective-C header files that I want to include in my Swift classes are checked like “Public,” under “Build Phases” → “Headers”.

Doing this, however, automatically exposes the project, using my infrastructure, for all the private Objective-C classes that the infrastructure uses.

Mapping modules (with a separate module)

Because of this, I studied the use of modular mapping, which is described here . I looked at posts from other users such as this and this , as well as how this is the Github repository .

I successfully got the following work:

 //SharedClasses/module.modulemap module SharedClasses { } //SharedClasses/module.private.modulemap module SharedClasses.Private { header "header.h" export * } 

The problem is that in my project (which imported this infrastructure):

 import Framework import Framework.SharedClasses 

it is allowed, and then the "hidden" classes of Objective-C are revealed. Perhaps this is how modules work? Is there any way to make them truly private?

Mapping modules (with own private module)

In addition, I tried to create a module.private.modulemap file in the root of my frame with the following contents:

 explicit module Framework.Private { header "header.h" export * } 

and then binding it to the settings of my target assembly in MODULEMAP_PRIVATE_FILE. However, when I do import Framework.Private in my Swift classes, a compiler error occurs:

"There is no such module 'Framework.Private'

I do not understand why this error occurs.

Mapping modules (with closed header)

I noticed that Clang docs has a private specifier:

A header with a private specifier may not be included outside the module itself.

I understand that since all Swift classes in my structure are already part of the Framework module, if I create a module.modulemap file with the following:

 framework module Framework { umbrella header "Framework.h" private header "header.h" export * module * { export * } } 

then everything should work! Objective-C headers are available only in a module (i.e., in Swift classes) and are not exposed to any project using a framework. Cool, but it doesn’t work ... the compiler simply does not recognize Objective-C classes. No other errors occur, but you cannot use headers, so that it is as if you did not include headers in the first place. WHAT FOR? And then why is it a private specifier?


Su, repeating my original question:

Is there a way to import Objective-C headers for use in Swift classes in the iOS dynamic structure while keeping them private and inaccessible from any project using the specified structure?

Thanks for reading and sorry for the long post. It was a long day (and night) ...

+13
source share
1 answer

You can find the method for this link .

Just create a folder (e.g. PrivateA) with the .modulemap module, where all the object headers that you want to use in your Swift class will be included. eg.

 module $(ModuleName)Private { header "header.h" export * } 

in Swift, you can use: import $(ModuleName)Private

therefore, the module by default excludes these headers when using import $(ModuleName) .

From my experiment, the test project can also import $(ModuleName)Private , but did not find useful code.

Try this way anyway.

+2
source

Source: https://habr.com/ru/post/1262582/


All Articles