脚本构建IPA缺失SwiftSupport文件夹,App Store提交报错ITMS-90426
问题根源分析
你的服务器构建脚本目前存在两个核心问题,导致SwiftSupport文件夹缺失:
使用废弃的
PackageApplication工具
苹果在Xcode 8之后就弃用了PackageApplication,这个旧工具不会自动处理Swift运行时依赖的打包,因此无法生成App Store要求的SwiftSupport文件夹。而本地Xcode构建用的是官方推荐的归档导出流程,会自动收集并打包Swift依赖库,所以本地IPA正常。手动解压重打包IPA破坏了结构
脚本最后一步解压IPA并重新打包的操作,不仅没有添加SwiftSupport,反而可能覆盖了原本(如果有)的相关文件——你的脚本只处理了Symbols文件夹,完全忽略了SwiftSupport的存在。
解决方案:改用官方归档导出流程
最可靠的解决方式是替换掉当前的xcodebuild build + PackageApplication流程,改用苹果官方推荐的xcodebuild archive + xcodebuild -exportArchive流程,这个流程会自动处理Swift依赖、签名和SwiftSupport文件夹的生成。
修改后的xc_package函数示例
function xc_package { echo "Building scheme \"$3\" => $1" # Calculated paths APP_ARCHIVE="$1/${APPNAME}.xcarchive" APP_IPA="$1/${APPNAME}.ipa" APP_DSYM_ZIP="$1/${APPNAME}.dSYM.zip" PROFILE="$4" UUID=`uuid_from_profile "$PROFILE"` [ -n "$UUID" ] || failed "Failed - missing provisioning profile UUID" echo "Building with Provisioning Profile $UUID (${PROFILE})" # Unlock keychain echo "Unlocking keychain..." security unlock-keychain -p "$BUILD_KEYCHAIN_PW" "${HOME}/Library/Keychains/login.keychain" || failed "Failed unlocking keychain" # xcodebuild archive (替代原clean build) XCODE_VERSION=`xcodebuild -version` XCODE_PATH=`xcode-select -p` echo "Building with $XCODE_VERSION in $XCODE_PATH profile : $UUID" export LC_CTYPE=en_US.UTF-8 xcodebuild \ -scheme "$3" \ -configuration Release \ clean archive \ -archivePath "$APP_ARCHIVE" \ PROVISIONING_PROFILE_SPECIFIER="$UUID" \ CODE_SIGN_IDENTITY="$5" | xcpretty || failed "Failed archiving" # 生成ExportOptions.plist(根据你的白标需求调整) EXPORT_OPTIONS_PLIST="$1/ExportOptions.plist" # 注意替换YOUR_BUNDLE_ID和YOUR_TEAM_ID为实际值,白标场景可通过变量动态传入 cat > "$EXPORT_OPTIONS_PLIST" << EOF <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>method</key> <string>app-store</string> <key>signingStyle</key> <string>manual</string> <key>provisioningProfiles</key> <dict> <key>YOUR_BUNDLE_ID</key> <string>$PROFILE</string> </dict> <key>teamID</key> <string>YOUR_TEAM_ID</string> </dict> </plist> EOF # 从归档导出IPA(自动包含SwiftSupport) echo "Exporting IPA from archive..." xcodebuild -exportArchive \ -archivePath "$APP_ARCHIVE" \ -exportPath "$1" \ -exportOptionsPlist "$EXPORT_OPTIONS_PLIST" | xcpretty || failed "Failed exporting IPA" # Zip dSYM(从归档中获取dSYM) echo "Zipping .dSYM..." zip -qr "$APP_DSYM_ZIP" "$APP_ARCHIVE/dSYMs/${APPNAME}.app.dSYM" }
关键修改说明
- 用
xcodebuild archive替代clean build:归档文件(.xcarchive)会完整保存App、dSYM、Swift依赖库等所有构建产物,是苹果推荐的标准构建产物格式。 - 用
xcodebuild -exportArchive生成IPA:这一步会自动根据ExportOptions.plist的配置,将Swift运行时库打包到IPA的SwiftSupport/iphoneos目录下,完全符合App Store的要求。 - 移除手动解压重打包IPA的步骤:官方导出的IPA已经包含所有必要文件,不需要再手动修改结构。
白标应用适配提示
如果你的白标应用需要动态修改Bundle ID,只需在生成ExportOptions.plist时,用变量替换YOUR_BUNDLE_ID即可(比如从配置文件或脚本参数中获取当前白标的Bundle ID)。
备选方案(不推荐):手动添加SwiftSupport文件夹
如果暂时无法切换到归档流程,你可以手动复制Swift运行时库到IPA中:
- 找到Xcode中的Swift库路径:
$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/ - 解压服务器生成的IPA,在解压目录下创建
SwiftSupport/iphoneos文件夹 - 将上述路径下的所有
.dylib文件复制到SwiftSupport/iphoneos目录 - 重新打包解压后的目录为IPA
但这种方法维护成本高,不同Xcode版本的Swift库路径可能变化,且容易遗漏文件,因此强烈推荐使用官方归档导出流程。
内容的提问来源于stack exchange,提问作者Kuldeep Tanwar




