如何在Xcode 10.2中构建分发跨设备模拟器的二进制框架并解决Swift头文件问题?
解决Xcode 10.2下Swift框架适配Swift/OC及多架构构建问题
嘿,针对你遇到的两个问题,我整理了实操性的解决方案,咱们一步步来:
一、修复MyFramework-Swift.h缺失模拟器定义的问题
Xcode 10.2确实存在这个bug:单独编译设备或模拟器版本时,生成的Swift桥接头文件只会包含对应架构的类/方法定义,导致通用框架的头文件不完整。既然Carthage已经内部修复了这个问题,咱们可以参考它的思路,通过构建脚本合并头文件来解决:
- 打开你的框架Xcode项目,切换到
Build Phases标签页 - 点击
+号,选择New Run Script Phase,把它拖到Compile Sources之后、Link Binary With Libraries之前 - 粘贴以下脚本(记得把
MyFramework替换成你的框架名称):
# 框架名称 FRAMEWORK_NAME="MyFramework" # 设备和模拟器构建产物路径 DEVICE_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneos" SIMULATOR_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" # 通用框架输出路径 UNIVERSAL_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-universal" # 确保通用目录存在 mkdir -p "${UNIVERSAL_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers" # 合并设备和模拟器的Swift桥接头文件,去重后覆盖到通用目录 if [ -f "${DEVICE_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}-Swift.h" ] && [ -f "${SIMULATOR_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}-Swift.h" ]; then cat "${DEVICE_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}-Swift.h" "${SIMULATOR_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}-Swift.h" | sort | uniq > "${UNIVERSAL_BUILD_DIR}/${FRAMEWORK_NAME}.framework/Headers/${FRAMEWORK_NAME}-Swift.h" fi
- 另外,检查你的Build Settings:确保
DEFINES_MODULE设为YES,SWIFT_OBJC_INTERFACE_HEADER_NAME保持默认的$(PROJECT_NAME)-Swift.h即可
二、构建并分发支持设备+模拟器的二进制框架
在Xcode 10.2中,你有两种可靠的方式生成通用(fat)框架:
方式1:手动用xcodebuild + lipo构建
适合不想依赖第三方工具的场景:
- 打开终端,进入你的框架项目根目录
- 先构建设备版本:
xcodebuild -scheme MyFramework -configuration Release -sdk iphoneos clean build
- 再构建模拟器版本:
xcodebuild -scheme MyFramework -configuration Release -sdk iphonesimulator clean build
- 创建通用框架目录并复制设备框架:
mkdir -p build/Release-universal cp -R build/Release-iphoneos/MyFramework.framework build/Release-universal/
- 合并二进制文件(核心步骤):
lipo -create build/Release-iphoneos/MyFramework.framework/MyFramework build/Release-iphonesimulator/MyFramework.framework/MyFramework -output build/Release-universal/MyFramework.framework/MyFramework
- 最后把咱们之前合并好的头文件替换进去(或者直接用上面的Run Script自动处理)
方式2:用Carthage一键构建
既然你提到Carthage已经内部解决了头文件问题,这是最省心的方式:
- 确保你已经安装了Carthage(如果没装,用
brew install carthage安装) - 在项目根目录执行:
carthage build --no-skip-current --platform iOS
- 构建完成后,通用框架会生成在
Carthage/Build/iOS/MyFramework.framework,这个框架的头文件已经包含了设备和模拟器的所有定义,直接分发给用户即可
分发注意事项
- 如果你的框架依赖其他库,记得把依赖也一并打包,或者告知用户通过Carthage/CocoaPods集成
- 不要直接把Xcode Archive导出的框架给用户,因为Archive默认只包含设备架构
- 若需要支持多平台(比如iOS+macOS),可调整
--platform参数为iOS,macOS
内容的提问来源于stack exchange,提问作者meaning-matters
相关产品推荐
相关产品推荐

