【发布时间】:2016-06-02 20:04:25
【问题描述】:
情况:
我有一个用 Swift 编写的 iOS 动态框架。我还有一堆用 Objective C 编写的类,我会在我的 Swift 类中使用它们(有些是公共的,有些是私有的)。 但是,我希望 Objective C 类不要暴露给使用我的框架的项目。
我尝试过的:
伞头
据我了解,我应该在我的总括头文件中使用#import header.h 导入,通常是FrameworkName.h,然后确保我希望包含在我的 Swift 类中的所有 Objective C 头文件都被标记作为“公共”,在 Build Phases -> Headers 下。
但是,这样做会自动将使用我的框架的项目公开给框架使用的所有私有 Objective C 类。
模块映射(带有单独的模块)
正因为如此,我研究了如何使用模块映射,它记录在 here。我查看了其他用户的帖子,例如this 和this,以及this Github repo。
我成功完成了以下工作:
//SharedClasses/module.modulemap
module SharedClasses {
}
//SharedClasses/module.private.modulemap
module SharedClasses.Private {
header "header.h"
export *
}
问题是在我的项目中(导入了这个框架),这个:
import Framework
import Framework.SharedClasses
是允许的,随后“隐藏的”Objective C 类就会暴露出来。也许这就是模块的工作方式?有没有办法让它们真正私有化?
模块映射(带有框架私有模块)
另外,我尝试在我的框架的根目录创建一个module.private.modulemap 文件,其内容如下:
explicit module Framework.Private {
header "header.h"
export *
}
然后在 MODULEMAP_PRIVATE_FILE 下将它链接到我的目标构建设置。但是,当我在框架的 Swift 类中执行 import Framework.Private 时,会引发编译器错误:
"没有这样的模块'Framework.Private'
我不明白为什么会出现这个错误。
模块映射(带有私有标头)
我注意到在Clang docs 中,提到了private 说明符:
带有私有说明符的标头不能从模块本身外部包含。
我的理解是,由于我框架中的所有 Swift 类都已经是模块 Framework 的一部分,如果我创建一个包含以下内容的 module.modulemap 文件:
framework module Framework {
umbrella header "Framework.h"
private header "header.h"
export *
module * { export * }
}
那么一切都应该正常工作! Objective C 头文件只能在模块中访问(即框架的 Swift 类),并且不会暴露给使用框架的任何项目。很酷,但它不起作用......编译器只是无法识别 Objective C 类。没有引发其他错误,但您不能使用标头,所以就像您一开始没有包含标头一样。 为什么?那么私有说明符是什么?
Soo,重申我原来的问题:
有什么方法可以在 iOS 动态框架中导入用于 Swift 类的 Objective C 标头,同时保持它们的私有性,并且不能从使用该框架的任何项目中访问?
感谢您的阅读,很抱歉发了这么长的帖子。这是漫长的一天(和夜晚)......
【问题讨论】:
-
我自己也在经历同样的头痛。你有没有让它工作?一旦您将标头标记为私有,它就无法在框架内部进行访问,这是没有意义的。然后就像,那么“私人”的意义何在?我一遍又一遍地重复同样的问题。
-
@marcelli407 不,我最终没有让它工作。我希望苹果能在今年的某个时候做点什么。目前,我决定坚持使用 Objective C 框架。我会确保在这里发布任何进一步的发现/更新!
-
@Jason,我必须在我的框架内创建另一个目标,它只包含目标 C 类,然后在我需要它的最终框架的快速代码中导入该目标。这允许仅在您的框架内公开类。
-
不确定开发人员是否可以访问 Objective C 目标。
-
我也被困在这一点上,花了几个小时后也没有找到任何解决方案。查看bugs.swift.org/browse/SR-655,似乎使用框架的外部项目需要私有模块这一事实是一个错误。 “暴露关于私有依赖的知识也是一个错误,但我认为需要设计来指定应该发生什么。如果你有兴趣,让我们在 swift-dev 上讨论它。”
标签: ios swift module frameworks clang