在 Mac App Store 上提交 Qt 5.3 应用程序以供审核
Posted
技术标签:
【中文标题】在 Mac App Store 上提交 Qt 5.3 应用程序以供审核【英文标题】:Submitting Qt 5.3 app for Review on Mac App Store 【发布时间】:2014-09-05 21:14:26 【问题描述】:对于上下文,我在 OSX 10.9 上使用 Qt 5.3.1 和 Xcode 5.1.1。
经过一番努力,我终于能够让我的应用程序的 PKG 文件通过 Application Loader 上传,并出现在 iTunes Connect 中我的应用程序的“预发布”构建列表中。但是,一旦我将构建添加到应用程序并单击“提交以供审核”,我会收到以下一系列错误:
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
The nested bundle must contain an executable that matches the CFBundleExecutable key in the Info.plist of the nested bundle .
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
ITC.apps.assetvalidation.DESKTOP_MISSING_NESTED_BUNDLE_IDENTIFIER.error.message
The Info.plist of the nested bundle must contain a valid CFBundleExecutable key.
我正在应用此答案中提到的注释:Sign a Framework for OSX 10.9
基本上,我通过 Xcode(在发布模式下)构建我的应用程序,然后使用我编写的一个小 Python 脚本来帮助自动化应用商店的准备工作。脚本的要点在这里:
import os
import shutil
import subprocess
import sys
bundleFolder = '/path/to/the/bundle/app'
qtFolder = '/path/to/qt/et/al'
entitlements = '/path/to/entitlesments/file'
print 'Bundle folder: ', bundleFolder
print 'Qt Folder: ', qtFolder
print 'Executing macdeploy'
subprocess.call([qtFolder + '/bin/macdeployqt', bundleFolder + '/Program.app'])
frameworks = ['QtConcurrent', 'QtCore', 'QtGui', 'QtMultimedia', 'QtMultimediaWidgets', 'QtNetwork',
'QtOpenGL', 'QtPositioning', 'QtPrintSupport', 'QtQml', 'QtQuick', 'QtSensors', 'QtSql',
'QtWebKit', 'QtWebKitWidgets', 'QtWidgets', 'QtXml', 'QtXmlPatterns']
for fwork in frameworks :
print ('Copying Info.plist to frameworks: ' + fwork)
fworkFolder = qtFolder + '/lib/' + fwork + '.framework/Contents/Info.plist'
destFolder = bundleFolder + '/Program.app/Contents/Frameworks/' + fwork + '.framework/Resources/'
if (os.path.exists(destFolder)) :
print 'Copying ' + fworkFolder + ' to ' + destFolder
shutil.copy(fworkFolder,destFolder)
print ('Deleting unnecessary PlugIns')
rmFiles = ['accessible','audio', 'mediaservice', 'printsupport']
for rmFile in rmFiles :
fullFile = bundleFolder + r'/Program.app/Contents/PlugIns/' + rmFile
if (os.path.exists(fullFile)) :
print ('Deleting directory: ' + fullFile)
shutil.rmtree(fullFile)
print ('Signing Qt Executables')
for fwork in frameworks :
subprocess.call([r'/usr/bin/codesign',
r'--deep',
r'--force',
r'--verify',
r'--verbose',
r'--sign',
r'3rd Party Mac Developer Application: [valid info]',
r'--entitlements',
entitlements,
bundleFolder + '/Program.app/Contents/Frameworks/' + fwork + '.framework/Versions/5/' + fwork
])
print ('Signing Bundle')
subprocess.call([r'/usr/bin/codesign',
r'--deep',
r'--force',
r'--verify',
r'--verbose',
r'--sign',
r'3rd Party Mac Developer Application: [valid info]',
r'--entitlements',
entitlements,
bundleFolder + '/Program.app',
])
print ("Building PKG")
subprocess.call([r'/usr/bin/productbuild',
r'--component',
bundleFolder + '/Program.app',
r'/Applications',
r'Program-Installer.pkg'
])
print ("Building Signed PKG")
subprocess.call([r'/usr/bin/productsign',
r'--sign',
r'3rd Party Mac Developer Installer: [valid info]',
r'Program-Installer.pkg',
r'Program-Installer-Signed.pkg'
])
我猜问题出在每个 Qt*.framework 的 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>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>5.3</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleExecutable</key>
<string>QtConcurrent</string>
<key>NOTE</key>
<string>Please, do NOT change this file -- It was generated by Qt/QMake.</string>
</dict>
</plist>
所以,我无法弄清楚 Mac App Store 为何抱怨。有人有什么想法吗?
谢谢!
【问题讨论】:
这里也一样。我认为在嵌套包的 plist 文件中包含主应用程序的可执行名称可能是一个新要求(即 YouApp.app 而不是框架名称),但我无法确认这个想法是真是假,因为 iTunesConnect 不允许我更新构建。我删除了一个旧版本,上传了一个新版本,但我在服务器上仍然只有一个版本(上传分离)。如果您知道如何重新上传二进制文件 - 我可以尝试我的想法并报告。 我通过增加内部版本号完成了新二进制文件的上传。 即使更改内部版本号后,我也无法在 iTunes 中看到新版本,但对于每次上传,我都会收到一封包含相同问题列表的邮件。所以,我想,我的想法行不通。 【参考方案1】:我终于明白了。 Qt Info.plist 文件似乎已损坏,即它们没有足够的信息,Apple 服务器上的最后一步验证失败。
为了解决这个问题,我从一个常规的 XCode 编译框架中获取了一个 Info.plist 文件,该框架包含在原生 Mac 应用程序中,并且之前通过了验证。内容是这样的:
<?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>BuildMachineOSBuild</key>
<string>13E28</string>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>BUNDLE_NAME</string>
<key>CFBundleIdentifier</key>
<string>BUNDLE_IDENTITY</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>BUNDLE_NAME</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>BUNDLE_VERSION</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>BUNDLE_VERSION</string>
<key>DTCompiler</key>
<string>com.apple.compilers.llvm.clang.1_0</string>
<key>DTPlatformBuild</key>
<string>5B1008</string>
<key>DTPlatformVersion</key>
<string>GM</string>
<key>DTSDKBuild</key>
<string>12F37</string>
<key>DTSDKName</key>
<string>macosx10.8</string>
<key>DTXcode</key>
<string>0511</string>
<key>DTXcodeBuild</key>
<string>5B1008</string>
</dict>
</plist>
我已经用占位符字符串替换了原始文件的包版本、名称和标识符,而不是将此文件用作 Qt 框架的 Info.plist,通过 Perl 脚本将占位符替换为正确的值。
进行了一些额外的修复,例如符合 this article 的正确符号链接,我终于让我的 Qt 4.8 应用程序通过审核,我相信您应该能够使用 Qt 5+ 获得相同的结果。
【讨论】:
这对我来说终于奏效了,我的应用终于获得了审核批准。谢谢! 谢谢!如果其他人想知道占位符使用什么字符串(例如 QtCore 4.8):BUNDLE_NAME -> QtCore, BUNDLE_IDENTITY -> QtCore, BUNDLE_VERSION -> 4 我有同样的问题,但是应用一个新的 plist 并没有解决它,它仍然说 CFBundleExecuitable 键错误。您能否提供有关如何修复此错误的更多信息? Hyndrix 已经为我的占位符声明了一些适当的(示例)值,包括一个用于 CFBundleExecuitable 键的值。此键应包含确切的框架名称,即代码框架的“QtCore”,xml 一的“QtXML”等等。 非常感谢您的建议。我已将 QtCore 设置为 CFBundleExecuitable,但 appstore 仍然出现此错误。非常困惑。可以指点一下吗?以上是关于在 Mac App Store 上提交 Qt 5.3 应用程序以供审核的主要内容,如果未能解决你的问题,请参考以下文章
上传到 Mac App Store 时出错:ITMS-90239
在没有 Mac 的情况下向 Apple App Store 提交 Ionic App [重复]
是否可以提交到不包括 OsX Mavericks 的 Mac App Store 下载