xcodebuild 从 Info.plist 中删除 CFBundleVersion 和 CFBundleShortVersionString

xcodebuild strips CFBundleVersion and CFBundleShortVersionString from Info.plist

我正在 Azure DevOps 中构建一个 iOS 应用程序。 *.ipa 的构建和导出工作正常,但上传到 App Store 失败并显示以下消息:

2020-10-05T14:02:27.9260830Z [14:02:27]: [Transporter Error Output]: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:27.9268950Z [14:02:27]: [Transporter Error Output]: ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.1474570Z [14:02:28]: Transporter transfer failed.
2020-10-05T14:02:28.1475590Z [14:02:28]: 
2020-10-05T14:02:28.1477810Z [14:02:28]: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.1480380Z ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2737090Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> DBG-X:   parameter ShouldUseRESTAPIs = false
2020-10-05T14:02:28.2741670Z 
2020-10-05T14:02:28.2743710Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> ERROR: ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.2745220Z 
2020-10-05T14:02:28.2746740Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> ERROR: ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2747600Z 
2020-10-05T14:02:28.2748330Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main> DBG-X: The error code is: 1102
2020-10-05T14:02:28.2748700Z 
2020-10-05T14:02:28.2749420Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:27 UTC] <main>  INFO: Done performing authentication.
2020-10-05T14:02:28.2749760Z 
2020-10-05T14:02:28.2749950Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750120Z 
2020-10-05T14:02:28.2750310Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750480Z 
2020-10-05T14:02:28.2750660Z [14:02:28]: [iTMSTransporter] 
2020-10-05T14:02:28.2750830Z 
2020-10-05T14:02:28.2751070Z [14:02:28]: [iTMSTransporter] Package Summary:
2020-10-05T14:02:28.2751270Z 
2020-10-05T14:02:28.2751460Z [14:02:28]: [iTMSTransporter]  
2020-10-05T14:02:28.2751630Z 
2020-10-05T14:02:28.2751950Z [14:02:28]: [iTMSTransporter] 1 package(s) were not uploaded because they had problems:
2020-10-05T14:02:28.2752240Z 
2020-10-05T14:02:28.2753070Z [14:02:28]: [iTMSTransporter]  /var/folders/24/8k48jl6d249_n_qfxwsl6xvm0000gn/T/d20201005-1299-rww8bj/1454404673.itmsp - Error Messages:
2020-10-05T14:02:28.2753450Z 
2020-10-05T14:02:28.2754860Z [14:02:28]: [iTMSTransporter]      ERROR ITMS-90057: "The bundle 'Payload/MyApp.app' is missing plist key. The Info.plist file is missing the required key: CFBundleShortVersionString. Please find more information about CFBundleShortVersionString at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring"
2020-10-05T14:02:28.2755720Z 
2020-10-05T14:02:28.2757000Z [14:02:28]: [iTMSTransporter]      ERROR ITMS-90056: "This bundle Payload/MyApp.app is invalid. The Info.plist file is missing the required key: CFBundleVersion. Please find more information about CFBundleVersion at https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion"
2020-10-05T14:02:28.2757770Z 
2020-10-05T14:02:28.2758440Z [14:02:28]: [iTMSTransporter] [2020-10-05 14:02:28 UTC] <main> DBG-X: Returning 1

果然,当我提取 ipa 文件并查看“Payload/MyApp.app/Info.plist”时,CFBundleVersionCFBundleShortVersionString 丢失了。

但是,这些值包含在原始的预编译 Info.plist 中,并且还在构建阶段使用 GitVersion 和 PlistBuddy 进行设置。我检查了变量设置是否正确,并尝试只使用硬编码版本,这并没有改变结果。

> echo 'iOsBundleVersion: $(iOsBundleVersion)'
iOsBundleVersion: 1.2.21
> echo 'iOsMarketingVersion: $(iOsMarketingVersion)'
iOsMarketingVersion: 1.2

azure-pipelines.yml(摘录):

- task: InstallAppleCertificate@2
  displayName: 'Install certificates'
  inputs:
    certSecureFile: $(certSecureFile)
    certPwd: '$(certPwd)'
    keychain: 'temp'

- task: InstallAppleProvisioningProfile@1
  displayName: 'Install provisioning profile'
  inputs:
    provisioningProfileLocation: 'secureFiles'
    provProfileSecureFile: $(provProfileSecureFile)

- task: CocoaPods@0
  displayName: 'Install CocoaPods'
  inputs:
    workingDirectory: '$(appRoot)'
    forceRepoUpdate: true
    projectDirectory: 'ios'

- task: Bash@3
  displayName: 'Set bundle version'
  inputs:
    targetType: 'inline'
    script: |
      /usr/libexec/PlistBuddy -c "Set CFBundleVersion $(iOsBundleVersion)" ./Info.plist
      /usr/libexec/PlistBuddy -c "Set CFBundleShortVersionString $(iOsMarketingVersion)" ./Info.plist
    workingDirectory: '$(appRoot)'

- task: Xcode@5
  displayName: 'Build project'
  inputs:
    actions: 'archive'
    configuration: 'Release'
    sdk: 'iphoneos'
    xcWorkspacePath: '$(appRoot)/MyApp.xcworkspace'
    scheme: '$(appName)'
    packageApp: true
    exportPath: '$(appRoot)/ios/build'
    xcodeVersion: 'default'
    signingOption: 'manual'
    signingIdentity: '$(APPLE_CERTIFICATE_SIGNING_IDENTITY)'
    provisioningProfileUuid: '$(APPLE_PROV_PROFILE_UUID)'
    args: '-UseModernBuildSystem=0'
    workingDirectory: '$(appRoot)'
    useXcpretty: true

这会产生以下命令:

xcodebuild -workspace /Users/runner/work/1/s/MyApp.xcworkspace -scheme MyApp archive -sdk iphoneos -configuration Release -archivePath /Users/runner/work/1/s/MyApp CODE_SIGN_STYLE=Manual CODE_SIGN_IDENTITY=Apple Distribution: xxxxxxxx (xxxxxxxxx) PROVISIONING_PROFILE=xxxxxxxx PROVISIONING_PROFILE_SPECIFIER= -UseModernBuildSystem=0 | /usr/local/lib/ruby/gems/2.6.0/bin/xcpretty --no-color

xcodebuild -exportArchive -archivePath /Users/runner/work/1/s/MyApp.xcarchive -exportPath /Users/runner/work/1/s/ios/build -exportOptionsPlist _XcodeTaskExportOptions.plist | /usr/local/lib/ruby/gems/2.6.0/bin/xcpretty --no-color

Info.plist(摘录):

<?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>CFBundleDevelopmentRegion</key>
    <string>en</string>
    <key>CFBundleDisplayName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.2</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.2.20</string>
    <key>ITSAppUsesNonExemptEncryption</key>
    <false/>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.utilities</string>
    <key>LSRequiresIPhoneOS</key>
    <true/>
    <key>NSAppTransportSecurity</key>

您可能需要检查项目中使用的所有 Info.plist。一些 info.plist 可能缺少密钥并导致上述错误。

您可以检查下面的脚本来搜索缺少 CFBundleShortVersionStringCFBundleVersion 的 info.plist。有关信息,请参阅 this thread

find . -name 'Info.plist' -not -path "*.storyboard*"  | while read file; do
echo $file;
{ plutil -p $file | grep CFBundleShortVersionString; } || echo Failed $file;
done;

您还可以查看,看看您的项目Target中是否添加了构建版本。如果没有,您可以尝试通过 XCode.

设置内部版本号和版本号

恐怕这个特定问题的解决方案与我在问题描述中包含的所有内容几乎完全无关。

这完全是我在 Azure DevOps 中创建管道的方式错误。我已经使用全局变量在一个作业中设置版本号并在另一个作业中读取它们,这是不可能的。最后,$(iOsBundleVersion)$(iOsMarketingVersion)没有设置。不幸的是,none 的构建脚本因任何合理的错误消息而失败。 Android 版应用程序的 gradle-build 实际上完成得很好。

从这个问题中可能没有新的教训可以吸取。我在另一个上下文中检查了 $(iOsBundleVersion)$(iOsMarketingVersion) 的值,这让我相信它们的设置是正确的——所以也许这个问题只是一个提醒,当“调试”任何代码。