You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

脚本构建IPA缺失SwiftSupport文件夹,App Store提交报错ITMS-90426

解决ITMS-90426: Invalid Swift Support - SwiftSupport文件夹缺失问题

问题根源分析

你的服务器构建脚本目前存在两个核心问题,导致SwiftSupport文件夹缺失:

  1. 使用废弃的PackageApplication工具
    苹果在Xcode 8之后就弃用了PackageApplication,这个旧工具不会自动处理Swift运行时依赖的打包,因此无法生成App Store要求的SwiftSupport文件夹。而本地Xcode构建用的是官方推荐的归档导出流程,会自动收集并打包Swift依赖库,所以本地IPA正常。

  2. 手动解压重打包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中:

  1. 找到Xcode中的Swift库路径:$(xcode-select -p)/Toolchains/XcodeDefault.xctoolchain/usr/lib/swift/iphoneos/
  2. 解压服务器生成的IPA,在解压目录下创建SwiftSupport/iphoneos文件夹
  3. 将上述路径下的所有.dylib文件复制到SwiftSupport/iphoneos目录
  4. 重新打包解压后的目录为IPA

但这种方法维护成本高,不同Xcode版本的Swift库路径可能变化,且容易遗漏文件,因此强烈推荐使用官方归档导出流程。

内容的提问来源于stack exchange,提问作者Kuldeep Tanwar

火山引擎 最新活动