能否在Xcode工作区创建XCFramework目标并作为依赖使用?
解决KMP生成的XCFramework在Xcode工作区的构建依赖问题
场景说明
我们的Xcode工作区包含三个项目:
- KMPFramework:Kotlin多平台实现,通过Gradle构建,已配置生成XCFramework以支持Apple Silicon模拟器
- FrameworkA、FrameworkB:常规iOS Framework,均依赖KMPFramework
- Application:iOS应用,仅调用FrameworkA和FrameworkB的接口
原方案通过带Run Script的Framework目标触发Gradle构建,但Xcode无XCFramework目标类型,无法沿用。当前采用Application Pre-Action调用脚本构建XCFramework,但存在诸多痛点。
当前方案的问题
- Pre-Action无法获取当前构建架构,Gradle会全量构建3种可用架构,开发阶段构建耗时大幅增加
- Pre-Action会在Clean操作前执行,虽能通过
CLANG_STATIC_ANALYZER_MODE判断规避,但实现不够优雅 - 整体方案繁琐,偏hack性质,维护成本高
优化解决方案
方案1:Aggregate目标+定向构建脚本+依赖前置
这是无需引入额外工具的原生Xcode解决方案:
- 在工作区新建Aggregate目标(命名为
BuildKMPFramework) - 给该Aggregate添加Run Script Build Phase,脚本可根据Xcode当前构建的架构和配置,调用Gradle只构建对应架构的XCFramework:
# 跳过Clean动作 if [[ "$ACTION" == "clean" ]]; then exit 0 fi # 映射Xcode架构到KMP目标 case "$ARCHS" in "arm64") KMP_TARGET="iosArm64" ;; "x86_64") KMP_TARGET="iosX64" ;; "arm64 x86_64") KMP_TARGET="iosSimulatorArm64 iosX64" ;; esac # 切换到KMP项目目录并执行构建 cd "$PROJECT_DIR/../KMPFramework" # 根据实际路径调整 ./gradlew assemble"$CONFIGURATION" -Pkotlin.mpp.targets="$KMP_TARGET" xcframework
- 分别给FrameworkA和FrameworkB添加Target Dependencies,将
BuildKMPFramework纳入依赖 - 在FrameworkA和FrameworkB的Build Phases中,确保
BuildKMPFramework的执行顺序在Compile Sources之前 - 首次构建前手动执行一次
BuildKMPFramework生成XCFramework,或在脚本开头添加判断:如果XCFramework不存在则先构建全量版本,避免Xcode初期校验失败。同时在FrameworkA/B的Build Settings中设置FRAMEWORK_SEARCH_PATHS指向XCFramework生成目录,开启ALWAYS_SEARCH_USER_PATHS
方案2:用CocoaPods管理KMPFramework依赖
如果团队已使用CocoaPods,这是更简洁的方案:
- 在KMP项目的Gradle配置中开启CocoaPods支持,自动生成Podspec文件
- 在工作区的Podfile中引入KMPFramework的Pod,让FrameworkA、FrameworkB和Application通过Pod依赖它
- 执行
pod install后,Xcode会自动处理XCFramework的依赖拉取、架构切片选择和构建顺序,完全无需手动编写脚本
关键优化点
- 方案1中通过
$ACTION判断直接跳过Clean时的Gradle构建,比原方案的CLANG_STATIC_ANALYZER_MODE判断更直观可靠 - 定向构建脚本只生成当前需要的架构切片,大幅缩短开发阶段的构建时间
- Aggregate目标的依赖前置确保了XCFramework在FrameworkA/B编译前已准备就绪,解决Xcode初期校验问题
内容的提问来源于stack exchange,提问作者GünterEbr
相关产品推荐
相关产品推荐

