如何自动化移除Cocoa Touch Framework模拟器架构适配App Store提交
嘿,这个问题我太熟了——做iOS框架开发几乎都会碰到这个两难:既要方便本地调试用通用框架,又要保证提交App Store时没有模拟器架构被拒。下面给你几个实用的自动化方案,从脚本优化到依赖管理工具都有:
方案1:扩展现有lipo脚本,自动区分构建场景
既然你已经配置了lipo的运行脚本,那只需要给它加个环境判断逻辑,让它根据当前是开发调试还是归档打包输出对应版本的框架:
- 打开你的Framework项目,进入「Build Phases」找到现有的lipo脚本阶段。
- 替换成下面的脚本,它会自动识别归档动作(用于App Store提交),只输出真机架构框架;日常开发则生成通用框架:
# 定义输出目录 UNIVERSAL_OUTPUTFOLDER="${BUILD_DIR}/${CONFIGURATION}-universal" DEVICE_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphoneos" SIMULATOR_BUILD_DIR="${BUILD_DIR}/${CONFIGURATION}-iphonesimulator" # 清空旧输出 rm -rf "${UNIVERSAL_OUTPUTFOLDER}" mkdir -p "${UNIVERSAL_OUTPUTFOLDER}" # 判断当前是否是归档构建(App Store提交用) if [ "${ACTION}" = "archive" ]; then # 归档时仅复制真机框架 cp -R "${DEVICE_BUILD_DIR}/${PRODUCT_NAME}.framework" "${UNIVERSAL_OUTPUTFOLDER}/" echo "Generated device-only framework for archive" else # 开发构建:先编译真机和模拟器版本 xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphoneos clean build xcodebuild -target "${PROJECT_NAME}" ONLY_ACTIVE_ARCH=NO -configuration "${CONFIGURATION}" -sdk iphonesimulator clean build # 用lipo合并架构 lipo -create -output "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ "${DEVICE_BUILD_DIR}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" \ "${SIMULATOR_BUILD_DIR}/${PRODUCT_NAME}.framework/${PRODUCT_NAME}" # 复制资源文件(如Assets、plist等) if [ -d "${DEVICE_BUILD_DIR}/${PRODUCT_NAME}.framework/Resources" ]; then cp -R "${DEVICE_BUILD_DIR}/${PRODUCT_NAME}.framework/Resources" "${UNIVERSAL_OUTPUTFOLDER}/${PRODUCT_NAME}.framework/" fi echo "Generated universal framework for development" fi - 之后你日常Run/Build时会得到通用框架,执行Archive操作时直接用生成的真机框架打包提交即可。
方案2:用CocoaPods分发,让工具自动处理
如果你的框架是要分发给其他开发者,CocoaPods是最省心的选择——它本身就内置了架构处理逻辑:
- 只需要写好你的
.podspec文件,开发者通过Pod集成后:- Debug阶段会自动使用适配模拟器/真机的架构;
- Release打包提交App Store时,CocoaPods会自动剔除模拟器架构,完全不需要手动操作。
- 哪怕是你自己的主App项目,把Framework作为本地Pod引入,也能享受这个自动处理的便利。
方案3:用Xcode构建配置轻量化控制
不想写脚本的话,可以直接通过Xcode的构建配置来区分架构:
- 打开Framework项目的「Build Settings」,找到「Excluded Architectures」:
- 针对Debug配置:留空,允许编译所有架构(包括模拟器的x86_64/arm64);
- 针对Release配置:添加
i386和x86_64(iOS平台),这样Release构建只会生成真机的arm64架构。
- 在你的主App项目中,同样给Release配置添加相同的排除架构,确保打包时不会混入模拟器切片。
- 这个方案的好处是零脚本,但注意M系列芯片的模拟器用的是arm64,如果你要在M1/M2上调试模拟器,需要确保Debug配置没有排除arm64。
验证架构是否正确
不管用哪种方案,都可以用这个命令确认框架的架构:
lipo -info /path/to/YourFramework.framework/YourFramework
- 通用框架会显示:
Architectures in the fat file: YourFramework are: arm64 x86_64 - 真机框架只会显示:
arm64
内容的提问来源于stack exchange,提问作者Andrea Mario Lufino




