我正在使用这个答案创建一个模块映射来为 CommonCrypto 创建一个模块,这样我就可以在框架中使用它。
然而,这样做意味着我使用此框架的任何项目都可以通过
import CommonCrypto
访问 CommonCrypto - 更糟糕的是,在另一个框架中声明 CommonCrypto 并将其导入到项目中会导致 Redefinition of module 'CommonCrypto'
错误。
即以下设置:
MainProject
|--> import FrameworkA - module map for CommonCrypto
|--> import FrameworkB - module map for CommonCrypto
有没有办法创建模块映射,但使其对其创建/使用的框架私有? (很像框架中 Swift 中的
internal
访问属性)。
llvm Clang 文档 显示了 private
属性,但我无法弄清楚将其放在模块映射中的位置,而且它甚至可能不是用于此目的!
还有一个 export
属性,但我还是不完全确定如何使用它......!
这是我用于 CommonCrypto 的模块映射 -
$(SDKROOT)
在构建阶段被交换到正确的位置(对于 iphoneos
或 iphonesimulator
SDK):
module CommonCrypto [system] [extern_c] {
umbrella header "$(SDKROOT)/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
这很好用(除了你不能“转到定义”,但我不介意)用于
FrameworkA
/ FrameworkB
。
免责声明:我还没有尝试过这个
CommonCrypto
,但它适用于我的情况,libz
一个可能的解决方案是创建一个
module.private.modulemap
,如 Clang 文档中所述
例如,在 FrameworkA 中,您可以为 FrameworkA 编写一个
module.modulemap
文件,如下所示:
module FrameworkACommon {
}
然后你会像这样创建一个
module.private.modulemap
文件
explicit FrameworkACommon.Crypto [system] [extern_c] {
header "/Applications/Xcode6-Beta5.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/usr/include/CommonCrypto/CommonCrypto.h"
link "CommonCrypto"
export *
}
然后对 FrameworkB 重复。
现在 CommonCrypto 是 FrameworkA 和 FrameworkB 中的私有模块,名称不会冲突。
我不完全确定这是否适用于这个问题中描述的用例,但我还是要发布一个答案,希望它可以帮助那些努力防止框架中的模块从外部访问的人应用程序。
我已经在一个类似的、最近的问题中发布了这个答案。
它涉及通过模块使用 Swift 的本机代码,而不使外部应用程序可以访问该模块。我认为这里真正的技巧,可能与这个问题最相关,是使用这个新的实验性 Swift 功能,它允许将访问级别修饰符设置为
import
,从而防止它泄漏包含框架的外部应用程序。
正如我在另一个 SO 问题中所说,此功能将在 Swift 6 中完全可用,默认情况下导入甚至应该是
internal
。