基于iOS Swift的动态框架中的Objective C类

Jas*_*son 20 frameworks module clang ios swift

情况:

我有一个用Swift编写的iOS dyanmic框架.我还有一堆用Objective C编写的类,我将在我的Swift类中使用(一些是公共的,一些是私有的).但是,我希望Objective C类不会暴露给使用我的框架的项目.


我尝试过的:

伞头

根据我的理解,我应该#import header.h在我的伞头文件中导入,这通常是FrameworkName.h,然后确保我希望包含在我的Swift类中的所有Objective C头文件都标记为"Public",在Build Phases下 - >标题.

但是,这样做会自动使用我的框架将项目公开给框架使用的所有私有Objective C类.

模块映射(带独立模块)

正因为如此,我已经研究过使用模块映射,这是记录在这里.我看过其他用户的帖子,比如这个这个,以及这个Github回购.

我成功完成了以下工作:

//SharedClasses/module.modulemap
module SharedClasses {
}

//SharedClasses/module.private.modulemap
module SharedClasses.Private {
    header "header.h"
    export *
}
Run Code Online (Sandbox Code Playgroud)

问题是在我的项目中(导入了这个框架),这个:

import Framework
import Framework.SharedClasses
Run Code Online (Sandbox Code Playgroud)

允许,然后暴露"隐藏的"Objective C类.也许这就是模块的工作原理?有没有办法让他们真正私密?

模块映射(带框架私有模块)

另外,我尝试module.private.modulemap在框架的根目录下创建一个文件,其中包含以下内容:

explicit module Framework.Private {
    header "header.h"
    export *
}
Run Code Online (Sandbox Code Playgroud)

然后在MODULEMAP_PRIVATE_FILE下链接我的目标的构建设置.但是,当我import Framework.Private在我的框架的Swift类中执行时,会抛出编译器错误:

"没有这样的模块'Framework.Private'

我不明白为什么会出现这种错误.

模块映射(带私有头)

我注意到在Clang文档中,private提到了一个说明符:

具有私有说明符的标头可能不包含在模块本身之外.

我的理解是,因为我的框架中的所有Swift类都已经是模块的一部分,所以Framework如果我创建一个带有以下内容的module.modulemap文件:

framework module Framework {
    umbrella header "Framework.h"

    private header "header.h"

    export *
    module * { export * }
}
Run Code Online (Sandbox Code Playgroud)

那么一切都应该有效!Objective C头只能在模块中访问(即框架的Swift类),并且不会暴露给使用框架的任何项目.很酷,但它不起作用......编译器只是不识别Objective C类.没有抛出其他错误,但是你不能使用标题,所以就像你没有首先包含标题一样.为什么?当时的私人说明者是什么?


Soo,重申我原来的问题:

是否有任何方法可以在iOS动态框架中导入用于Swift类的Objective C标头,同时保持它们是私有的,并且无法使用所述框架从任何项目访问?

感谢阅读,并为长篇文章感到抱歉.这是漫长的一天(和夜晚)......

Jen*_*ong 2

您可以从此链接找到一些方法。

只需使用 module.modulemap 创建文件夹(例如PrivateA),其中包含您需要在 Swift 类中使用的所有对象标头。例如

module $(ModuleName)Private {
    header "header.h"
    export *
}
Run Code Online (Sandbox Code Playgroud)

在 Swift 中,您可以使用:import $(ModuleName)Private

因此,默认模块在使用时排除这些标头import $(ModuleName)

从我的实验来看,测试项目还可以import $(ModuleName)Private,但是没有发现什么有用的代码。

无论如何都尝试一下这个方法。