最近在学习制作Swift Framework项目,期间遇到需要引用OC系统库<CommonCrypto/CommonCrypto.h>的问题,正常的Swift项目可以通过创建Bridge的方式来连接OC库,但是framework不行,编译的时候会提示错误:
using bridging headers with framework targets is unsupported
错误配置
找了很多资料都是新建一个module.map文件,然后在文件里面配置module的映射路径,然后在项目配置里做一系列配置。
module CommonCrypto [system] {
header "/Applications/Xcode6-Beta5.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator8.0.sdk/usr/include/CommonCrypto/CommonCrypto.h"
link "CommonCrypto"
export *
}
==但这是不行的==,主要是因为header中的映射路径是硬代码,是写死的,对不同版本的系统来说就是致命的。
后来终于在Stack Overflow中找到了一个简单粗暴的解决方案。
正确配置
-
打开framework项目,在TARGETS里面新建一个Aggregate文件,并命名为CommonCryptoModuleMap。
- 选中该TARGET,切换到Build Phases中,新建一个Run Script,并填写脚本:
# This if-statement means we'll only run the main script if the CommonCryptoModuleMap directory doesn't exist
# Because otherwise the rest of the script causes a full recompile for anything where CommonCrypto is a dependency
# Do a "Clean Build Folder" to remove this directory and trigger the rest of the script to run
if [ -d "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap" ]; then
echo "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap directory already exists, so skipping the rest of the script."
exit 0
fi
mkdir -p "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap"
cat <<EOF > "${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap/module.modulemap"
module CommonCrypto [system] {
header "${SDKROOT}/usr/include/CommonCrypto/CommonCrypto.h"
export *
}
EOF
如图:
上面使用了${SDKROOT}来代替了硬编码,这样在不同版本下可以保持相对路径。
如果你需要跨平台使用,那么还需在Build Settings中的Supported Platforms配置平台信息。
-
选中框架TARGET,在Build Phases中的Target Dependencies中添加CommonCryptoModuleMap,确保在框架编译的时候CommonCryptoModuleMap会提前生成。
选中框架TARGET,在Build Settings中的Header Search Paths添加
$(inherited)
${BUILT_PRODUCTS_DIR}/CommonCryptoModuleMap
- 编译一次,然后就可以在Swift Framework项目中直接导入CommonCrypto使用了。
import CommonCrypto