Submitting Qt 5.3 app for Review on Mac App Store

For context, I am using Qt 5.3.1 with Xcode 5.1.1 on OSX 10.9.

After some struggle, I was finally able to get my application's PKG file to upload through Application Loader and appear in my "Prerelease" build list for my App in iTunes Connect. However, once I add the build to the app and click "Submit for Review" I get the following slew of errors:

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.

I am applying the notes mentioned in this answer: Sign a Framework for OSX 10.9

Basically, I build my application through Xcode (in Release mode) and then I use a little Python script I wrote to help automate the prep for the app store. A gist of the script is here:

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'
])

I'm guessing the problem lies within the Info.plist files for each individual Qt*.framework but when I look inside them, the info looks valid as far as I can tell, for example:

<?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>

So, I cannot figure out why the Mac App Store is complaining. Does anyone have any thoughts?

Thank you!


I finally got though it. It seems like Qt Info.plist files are corrupt, ie they do not have enough info and the last-step validation on Apple server fails.

In order to solve the issue I took an Info.plist file from a regular XCode-compiled framework that was included in a native Mac app and passed validation before. The content was like this:

<?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>

I have replaced bundle version, name and identifier of the original file with placeholder strings, than I used this file as Info.plist for Qt frameworks, replacing the placeholders with correct values via Perl script.

Having some additional fixes like proper symlinks conforming this article, I finally got my Qt 4.8 app passed for review, I believe you should be able to get same result with Qt 5+.

链接地址: http://www.djcxy.com/p/78996.html

上一篇: 如何为QMacStyle获取完整的Qt样式表

下一篇: 在Mac App Store上提交Qt 5.3应用程序进行审查