Bienvenue sur le forum !

Si vous souhaitez rejoindre la communauté, cliquez sur l'un de ces boutons !

Qt 5 : 5.9.0 - Qt Creator : 4.3.0 - Qt Installer : 2.0.3 - JOM : 1.1.2 - Qt Build suite : 1.7.0 - VS Qt 5 : 2.0.0

Retour d'expérience d'une première publication sur le Mac App Store

Bonjour

C'est l'histoire d'un mec qui essaye de poster son application Qt/Qml sur le "Mac App Store"

Après avoir porté zeecrowd sur Mac OS (voire précédent post ici ), je pensai avoir fait le plus dur ...
C'est sans compter sur la forteresse ": "Mac App Store".

Voici pêle-mêle la liste des choses que j'ai dut faire :

0 : iTunes connect


La première chose est de créer dans iTunes Connect le nom de votre application et d'y renseigner toutes les informations administratives vous concernant ainsi qu'un descriptif de l'application.

Pour publier votre package vous allez utiliser ensuite "Application Loader" qui se trouve dans XCode.
"XCode" se trouve lui dans le répertoire "/Applications", et "Application Loader" se lance depuis le menu "XCode/Open Developper Tool"

1 : Pas de dmg mais un pkg


Pour publier mon application via un site Web j'avais créer simplement une archive ".dmg" grâce à l'utilitaire fournit par Qt : "macdeployqt"
Mais pour le "Mac App Store" ça ne sert à rien :-(
Il faut un package ".pkg"

Ca c'est assez simple :

productbuild --version <numéro de version> --component Zeecrowd.app /Applications UnsignedZeecrowd.pkg

Le numéro de version doit être composé de trois chiffres séparés par un point.
La ligne de commande dit : "je package le bundle Zeecrowd.app en UnsignedZeecrowd.pkg et il s'installera sur le poste client dans le répertoire 'Applications'".
Le package n'est pas signé il faudra ensuite le signer pour être accepté par le "Mac App Store". Il faut utiliser pour cela le certificat "3rd Party Mac Developper Installer: ..."

productsign --sign "3rd Party Mac Developer Installer: ..." UnsignedZeecrowd.pkg macosx2/Prod/Zeecrowd.pkg
J'ai fait tout cela en utilisant le Bundle que j'avais obtenu grâce à "macdeployqt" et je suis tombé dans pleins de trous (aie) .... :(

En effet "Application Loader" (premier mur à franchir) et la phase de vérification du "Mac App Store" (deuxième mur à franchir : retour par mail) m'ont rejeté régulièrement en signalant des anomalies dans le Bundle.

2 : Un Info.plist correct


Personnellement je me suis fait jeter sur le numéro de version et de "BundleId".
Voici le "Info.plist" de Zeecrowd qui au final à été accepté par le "Mac App Store"

<?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>NSPrincipalClass</key>
<string>NSApplication</string>
<key>CFBundleIconFile</key>
<string>Zeecrowd.icns</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleGetInfoString</key>
<string>Created by Qt/QMake</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0.384</string>
<key>CFBundleShortVersionString</key>
<string>1.0.384</string>
<key>CFBundleExecutable</key>
<string>Zeecrowd</string>
<key>CFBundleIdentifier</key>
<string>@BUNDLEID@</string>
<key>NOTE</key>
<string>This file was generated by Qt/QMake.</string>
<key>LSApplicationCategoryType</key>
<string>public.app-category.productivity</string>
</dict>
</plist>

3 : Qt Framework dans le Bundle


Je n'ai qu'un mot à dire : Vivement la 5.4 !!!!!!

Et oui, le déploiement par "macdeployQt" du framework Qt c'est n'importe quoi pour le "Mac App Store" :-(
Tout est assez bien expliqué ici :

http://qt.developpez.com/actu/76819/Qt-5-4-pourra-signer-des-applications-OS-X-compatibles-avec-Yosemite-10-10/

On commence par fournir un Info.plist correct pour tout les frameworks Qt :

<?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>CFBundleVersion</key>
<string>5.2.0</string>
<key>CFBundleShortVersionString</key>
<string>5.2.0</string>
<key>CFBundleExecutable</key>
<string>@EXECUTABLE@</string>
<key>CFBundleIdentifier</key>
<string>com.jabberbees.Zeecrowd</string>
</dict>
</plist>

@EXECUTABLE@ sera remplacé à chaque fois par le nom du framework Qt.
Je suis pas un dieu en bash donc j'ai fait un truc simple :

ROOTPATH=`pwd`

for FMWK in $QT_FMWKS; do
cp QtInfo.plist Zeecrowd.app/Contents/Frameworks/${FMWK}.framework/Resources/Info.plist
sed -i '' -e "s/@EXECUTABLE@/${FMWK}/g" Zeecrowd.app/Contents/Frameworks/${FMWK}.framework/Resources/Info.plist

cd Zeecrowd.app/Contents/Frameworks/${FMWK}.framework
cd Versions
ln -s 5 Current
cd ..
ln -s Versions/Current/${FMWK} ${FMWK}
mv Resources Versions/Current
ln -s Versions/Current/Resources Resources
cd $ROOTPATH

done

Mais malheureusement ce n'est pas suffisant les libraries dynamiques (dylib) ne peuvent pas être dans le répertoire "Resources" :-(
Et les "controls qml" y sont :-(
Donc le mieux est de déplacer les libraries dans le répertoire "PlugIns" et de créer un lien symbolique.

Voici un exemple, et j'ai fait ceci pour toutes les (.dylib) :

mv Zeecrowd.app/Contents/Resources/qml/Qt/labs/folderlistmodel/libqmlfolderlistmodelplugin.dylib Zeecrowd.app/Contents/PlugIns/libqmlfolderlistmodelplugin.dylib
cd Zeecrowd.app/Contents/Resources/qml/Qt/labs/folderlistmodel
ln -s ../../../../../PlugIns/libqmlfolderlistmodelplugin.dylib libqmlfolderlistmodelplugin.dylib

5 : Les API Quick Time ne sont plus supportées ...


Bein oui :-(. L'application est rejetée par le Mac App Store car il détecte dans une des librairies du framework Qt l'utilisation d'une "API Quick Time".

C'est la librairie "libqqt7engine.dylib" qui est en cause : donc une solution radicale :-( :

rm Zeecrowd.app/Contents/PlugIns/mediaservice/libqqt7engine.dylib

Une bonne nouvelle : les API Quick Time ne sont plus utilisées dans la 5.4 :)

6 : Une "SandBox" ... un fichier .entitlements


Bon à ce stade on se dit qu'on en a fait déjà pas mal mais une autre surprise nous attend ...

Une application qui se trouve dans le Mac App Store est apparemment exécutée sur le poste client dans une "SandBox". Et donc il faut determiner à quoi aura accès l'application.
Ces informations sont à mettre dans un fichier avec pour extension ".entitlements".
Celui de l'application Zeecrowd ressemble à ceci :

<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.network.client</key>
<true/>
<key>com.apple.security.network.server</key>
<true/>
<key>com.apple.security.files.downloads.read-write</key>
<true/>
<key>com.apple.security.files.bookmarks.app-scope</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
<key>com.apple.security.files.user-selected.executable</key>
<true/>
</dict>
</plist>

Le fichier ".entitlements" doit être placé dans le répertoire "Resources" du "bundle", et signalé lors de la signature du bundle avec le bon certificat :

codesign --force --verify --verbose --deep --sign "3rd Party Mac Developer Application: ..." --entitlements Zeecrowd.app/Contents/Resources/Zeecrowd.entitlements Zeecrowd.app

Avec tout ça on est bon et les vérifications automatiques du Mac App Store accepte le package et il y a plus qu'à attendre la validation humaine ....


A une chose quand même : Comme l'application tourne dans une "SandBox" le système créé un répertoire dans "/Users//Library/" qu'il faut utiliser ... mais ça c'est une autre histoire ...

Réponses

  • Bonjour,

    Le post ci dessus n'a pas été suffisant pour poster mon application Qt/Qml utilisant le WebKit sur le Mac Apple Store
    J'ai suivit les indications suivantes :

    http://wiki.phisys.com/index.php/How-To_Qt5.3_Mac_AppStore

    C'est en anglais ...

    Si c'est concluant je vous fait un retour en français ....
  • Bonjour,

    merci beaucoup pour ce post détaillé, j'ai moi aussi beaucoup galéré avec la publication d'applications sur l'AppStore. Mon conseil serait celui-ci : utilisez plutôt XCode pour le packaging. Je m'explique :
    - vous créez votre application avec QtCreator, tout bien, la testez etc.
    - au moment de la mettre sur l'AppStore, comme XCode sait tout faire comme il faut (ou presque), et surtout générer les certificats, les fichiers d'entitlements et cie, utilisez XCode avec la commande
    qmake -spec macx-xcode
    Cette commande doit être exécutée dans le même répertoire que votre fichier .pro

    Vous récupérez alors un fichier .xcodeproj que vous ouvrez, en double-cliquant dessus, dans XCode.
    Après c'est du Xcode...

    bon courage !
    Tristan
  • Pas bête ... ;)

    Mais là je suis confronté au problème suivant : Qt 5.3 n'est pas compatible avec le dernier Mac App Store .. il faut le recompiler avec la dernière version ICU .. QtWebProcess : on oubli ...

    J'ai fait tout ça et j'attends de voire la validation de l'équipe Apple avant de faire un nouveau post
  • Ah là là... c'est vrai que question compatibilité on a toujours plusieurs trains de retard chez Qt ;)
  • Bonjour

    Quelques news de la publication sur MacAppStore

    Après "moultes" essais j'ai finit par abandonner le portage de QWebView pour le MacAppStore avec la version 5.3.

    Malgré une re-compilation de Qt avec la dernière version de ICU (je ferai un poste plus détaillé une fois validation de l'application par Apple) il reste dans libicuuc.dylib des utilisations d'API bannies par Apple.

    J'ai plutôt opté pour une solution temporaire de contournement (pas de WebView qml sur macos) en attendant un test avec la 5.4 :mad:
  • Bonjour

    Ca y est, on a réussi a poster notre application sur le Mac App Store.
    Cela veux dire que l'application est maintenant accessible depuis l'"App Store" sur un ordinateur Macintosh.

    Bon je vais vous présenter le "bash" qui m'a permit de faire accepter notre application par l'équipe de validation d'Apple
    (he oui il y a une équipe de testeurs/validateurs qui vérifie votre application ....)

    Notre application Zeecrowd est un composée de Qt C++ (compilé en librairies dynamiques) et de Qml. Pour cela il va être nécessaire de livrer en plus des librairies Qt : les plugins et resources Qml.
    Nous n'utilisons pas l'utilitaire "macdeployqt" afin de bien tout comprendre ce que l'on doit faire.

    ENUMERATION DES LIVRABLES


    Voici la liste des librairies Qt qui vont êtres déployées. Nous allons les positionner dans la variable QTLIBS :

    QTLIBS="QtCore QtNetwork QtSql QtGui QtSvg QtScript QtOpenGL QtWidgets \
    QtPrintSupport QtWebSockets QtXml QtPositioning QtSensors QtMultimedia QtMultimediaQuick_p QtMultimediaWidgets QtQml QtQuick QtBluetooth QtDeclarative QtXmlPatterns QtQuickParticles QtNfc"

    Et la liste des répertoires des resources Qml que l'on met dans la variable QMLLIBS :

    QMLLIBS="Qt QtAudioEngine QtBluetooth QtGraphicalEffects QtMultimedia Qt QtNfc QtQml QtQuick QtQuick.2 QtSensors"

    Et enfin la liste des plugins dans PLUGINS:

    PLUGINS="sqldrivers imageformats iconengines platforms printsupport accessible \
    position mediaservice playlistformats sensors sensorgestures bearer audio"
    Comme vous pouvez le voire QtWebKit et QtWebKitWidgets ont été supprimés de la liste.
    En effet malgré quelques articles dessus, un essai de recompilation du framework avec la dernière version de ICU n'a malheureusement rien donné :mad:
    Le composant WebKit Qml a besoin d'API ICU qui ne sont pas compatibles avec le MacAppStore. Voilà pourquoi nous avons décidé de retirer ces modules
    du livrable et de nous en passer pour la version Mac.
    Heureusement une combinaison de Loader et Qt.platform en qml permet de detecter la plateforme et de charger ou pas le composant WebKit.

    DEFINITION DES PATHS ET VARIABLES UTILITAIRES


    On met dans BUNDLE le nom de notre application pour nous ca sera Zeecrowd :

    BUNDLE="Zeecrowd"
    Le répertoire cible où l'on va générer votre package :

    DEST="Ce que vous voulez"
    Le répertoire où QtCreator vous a généré votre Bundle (.app) :

    SRC="truc bidule machin chose build-Foundation_All_Portable-Desktop_Qt_5_3_clang_64bit-Release ...."
    Le répertoire où se trouve votre distribution QT :

    QTDIR="Le path vers la distrib qt /Qt5.3.2/5.3/clang_64"
    COPIE DU BUNDLE QUE L'ON VA MODIFIER


    QtCreator vous a généré un Bundle (.app).
    Nous allons modifier ce dernier afin de lui ajouter tout ce qui est nécessaire pour montrer "patte blanche" au MacAppStore.
    Donc on va en faire une copie (l'histoire de pas "pourrir" celui que Qtcreator nous a si gentiment généré).
    On en profite faire un nettoyage du repertoire cible et le régénérer (Allez hop place nette ..).

    echo "Clean"
    rm -rf $DEST

    echo "Copy Applications Files"
    mkdir -p $DEST
    cp -Rp $SRC $DEST/$BUNDLE.app
    LE FICHIER ENTITLEMENTS


    Ce fichier est nécessaire et positionne les droits d'accès de l'application. Ce fichier est inspecté à la loupe par l'équipe de vérification.
    Voici celui que l'on a utilisé pour Zeecrowd (nom de notre application :-))

    <?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>com.apple.security.app-sandbox</key>
    <true/>
    <key>com.apple.security.network.client</key>
    <true/>
    <key>com.apple.security.network.server</key>
    <true/>
    <key>com.apple.security.files.downloads.read-write</key>
    <true/>
    <key>com.apple.security.files.bookmarks.app-scope</key>
    <true/>
    <key>com.apple.security.files.user-selected.read-write</key>
    <true/>
    </dict>
    </plist>

    Ce fichier doit être copié dans le repertoire Resources du bundle

    ENTITLEMENTS="Zeecrowd.entitlements"
    cp -p $ENTITLEMENTS $DEST/$BUNDLE.app/Contents/Resources/
    LE FICHIER INFO.PLIST

    C'est un peu une carte d'identité de votre bundle. Voici ce qu'elle contient pour Zeecrowd:

    <?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>NSPrincipalClass</key>
    <string>NSApplication</string>
    <key>CFBundleIconFile</key>
    <string>Zeecrowd.icns</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleGetInfoString</key>
    <string>Created by Qt/QMake</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleVersion</key>
    <string>1.2.3</string>
    <key>CFBundleShortVersionString</key>
    <string>1.2.3</string>
    <key>CFBundleExecutable</key>
    <string>Zeecrowd</string>
    <key>CFBundleIdentifier</key>
    <string>com.jabberbees.Zeecrowd</string>
    <key>NOTE</key>
    <string>This file was generated by Qt/QMake.</string>
    <key>LSApplicationCategoryType</key>
    <string>public.app-category.productivity</string>
    </dict>
    </plist>

    On peut y voire :

    CFBundleIconFile : Le nom du fichier contenant les icônes (Ce fichier a été généré par Qtcreator et mit dans le Bundle)
    CFBundleVersion : Le numéro de version sur 3 chiffres.
    CFBundleExecutable : Le nom de l'executable
    CFBundleIdentifier : L'identifiant au programme Developper de Apple.
    LSApplicationCategoryType : Catégorie principale dans laquelle av se trouver l'application dans le MacAppStore.

    On doit placer ce fichier directement dans le répertoire Contents du bundle:

    echo "Copy my info.plist"
    cp Info.plist $DEST/$BUNDLE.app/Contents/Info.plist
    LE FICHIER QT.CONF


    Qt a besoin de connaître où l'on a placé ses fichiers de resources Qml et ses plugins. Le fichier Qt.conf va l'aider à retrouver ses petits ]:D .

    [Paths]
    Plugins = PlugIns
    Imports = Resources/qml
    Qml2Imports = Resources/qml
    On place le tout dans le repertoire Resources du bundle:

    echo "Copy qt.conf"
    cp qt.conf $DEST/$BUNDLE.app/Contents/Resources/.
    LES LIBS DU FRAMEWORK QT


    Bon on attaque le gros morceaux la copie de toutes le librairies Qt. En fait chaque librairie est aussi un Bundle (.framework).
    Et là pas de bol la structure des "Bundle" Qt de Qt 5.3 sont incompatibles avec le MacAppStore (en même temps ca serait trop simple)

    Tout d'abords il manque un fichier Info.plist dans chacun de ces "Bundle". En voici un compatible que l'on mettra dans un fichier QtInfo.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>CFBundleVersion</key>
    <string>5.3.0</string>
    <key>CFBundleShortVersionString</key>
    <string>5.3.0</string>
    <key>CFBundleExecutable</key>
    <string>@EXECUTABLE@</string>
    <key>CFBundleIdentifier</key>
    <string>com.jabberbees.Zeecrowd</string>
    </dict>
    </plist>
    La chaine de caractères @EXECUTABLE@ sera remplacée par le nom du bundle Qt.
    Le code shell ci dessous va copier chaque bundle Qt dans le repertoire Frameworks de notre bundle et refaire la hiérarchie de répertoires de chaque Bundle Qt comme suit :

    Exemple de QtCore

    Zeecrowd.app/Contents/Frameworks/QtCore.framework/QtCore -> Versions/Current/QtCore
    Zeecrowd.app/Contents/Frameworks/QtCore.framework/Resources -> Versions/Current/Resources
    Zeecrowd.app/Contents/Frameworks/QtCore.framework/Versions/5
    Zeecrowd.app/Contents/Frameworks/QtCore.framework/Versions/Current -> 5
    Zeecrowd.app/Contents/Frameworks/QtCore.framework/Versions/5/QtCore
    Zeecrowd.app/Contents/Frameworks/QtCore.framework/Versions/5/Resources/Info.plist
    Voici le shell :

    echo "copy Qt libs"
    for L in $QTLIBS ; do

    cp -Rp $QTDIR/lib/$L.framework $DEST/$BUNDLE.app/Contents/Frameworks

    # on copie un InfoPlist correct
    cp QtInfo.plist $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Contents/Info.plist
    sed -i '' -e "s/@EXECUTABLE@/$L/g" $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Contents/Info.plist

    # remove all unnecessary header files and debug version:
    rm -f $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/$L\_debug
    rm -f $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/5/$L\_debug
    rm -f $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/$L.prl
    rm -f $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/$L\_debug.prl
    rm -f $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Headers
    rm -rf $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/5/Headers
    rm -rf $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Contents

    mkdir $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/Current/Resources
    cp QtInfo.plist $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/Current/Resources/Info.plist
    sed -i '' -e "s/@EXECUTABLE@/${L}/g" $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/Current/Resources/Info.plist

    ln -s Versions/Current/Resources $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Resources

    done

    LES PLUGINS


    Maintenant c'est au tour des plugins. Ce sont de simples librairies dynamiques regroupées par répertoire.
    On recopie tout et on supprime les versions debug.

    echo "copy plug-ins"
    for P in $PLUGINS ; do
    mkdir -p $DEST/$BUNDLE.app/Contents/PlugIns/$P/
    cp -Rp $QTDIR/plugins/$P/*.dylib $DEST/$BUNDLE.app/Contents/PlugIns/$P/
    done
    Deux librairies utilisent des API interdites par le MacAppStore alors on les supprime (heureusement nous en avons pas besoin)

    echo remove libqqt7engine.dylib
    rm $DEST/$BUNDLE.app/Contents/PlugIns/mediaservice/libqqt7engine.dylib
    echo remove libqsqlodbc.dylib
    rm $DEST/$BUNDLE.app/Contents/PlugIns/sqldrivers/libqsqlodbc.dylib
    LES FICHIERS QML DE QT


    Là c'est plus simple (qu'on croit ...) il n'y a plus qu'a les recopier dans le repertoire Resources :

    echo "copy qml directory"
    mkdir -p $DEST/$BUNDLE.app/Contents/Resources/qml
    for I in $QMLLIBS ; do
    cp -r $QTDIR/qml/$I $DEST/$BUNDLE.app/Contents/Resources/qml/
    done
    On fait un petit nettoyage pour supprimer tout les fichiers debug :

    echo "Remove all _debug.dylib"
    DEBUGLIBS=`cd $DEST/$BUNDLE.app/Contents/; find . -name \*\_debug.dylib -print` # extract all our *_debug.dylib libs
    for D in $DEBUGLIBS ; do
    rm -f $DEST/$BUNDLE.app/Contents/$D
    done
    Mais ca suffit pas ... On a pas le droit d'avoir des binaires dans le repertoire Resources :-(.
    Voilà pourquoi on va recopier toutes les librairies dynamiques (.dylib) dans le repertoire plugins et on créé des liens symboliques entres les deux.
    Comme cela le MacAppStore accepte le package et Qt retrouve quand même ses billes.

    echo "Symbolique link from resources/qml to Plugins/qml"
    mkdir -p $DEST/$BUNDLE.app/Contents/PlugIns/qml
    DISTQMLDIRPLUGINS=`cd $DEST/$BUNDLE.app/Contents/Resources/qml; find . -name \*.dylib -print` # extract all our *.dylib libs
    for QD in $DISTQMLDIRPLUGINS ; do

    # echo $QD
    IFS='/ ' read -a array <<< "$QD"
    nbrelem="${#array[@]}"
    tmp=""
    for element in "${array[@]}"; do
    tmp+="../"
    done

    mv $DEST/$BUNDLE.app/Contents/Resources/qml/$QD $DEST/$BUNDLE.app/Contents/PlugIns/qml/.
    ln -s $tmp./PlugIns/qml/${array[$nbrelem - 1]} $DEST/$BUNDLE.app/Contents/Resources/qml/$QD
    done

    CHANGEMENT DES REFERENCES


    Bon à ce stade là (si on a pas craqué avant) on a un bundle de notre application qui contient tout les fichiers et au bon endroit.
    Seulement à force d'avoir tout bougé il faut maintenant re-référencer les chemins utilisés dans les binaires et le librairies dynamiques.

    L'utilitaire "install_name_tool" est là pour ca.

    On va tout d'abords determiner le prefix utilisé pour les librairies Qt. En fait c'est le path ou est installé Qt.
    Pour trouver ce prefix le mieux est d'utiliser l'utilitaire otool sur une librairie de Qt et d'en determiner ainsi le prefix :

    Exemple :

    otool -L Zeecrowd.app/Contents/Frameworks/QtCore.framework/QtCore
    La sortie est la suivante :

    /Users/CestMoi/Qt5.3.2/5.3/clang_64/Frameworks/QtCore.framework/Versions/5/QtCore (compatibility version 5.3.0, current version 5.3.2)
    /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.5)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 169.3.0)
    /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices ( ......
    Mon prefix sera donc le suivant :

    PREFIX="/Users/CestMoi/Qt5.3.2/5.3/clang_64"
    Le petit bout de code suivant s'occupe des librairies Qt et de mon binaire Zeecrowd :

    echo "install_name_tool QTLIBS ...."
    for I in $QTLIBS ; do
    install_name_tool -id "@executable_path/../Frameworks/$I.framework/Versions/5/$I" "$DEST/$BUNDLE.app/Contents/Frameworks/$I.framework/Versions/5/$I"
    install_name_tool -change $PREFIX/lib/$I.framework/Versions/5/$I @executable_path/../Frameworks/$I.framework/Versions/5/$I $DEST/$BUNDLE.app/Contents/MacOS/Zeecrowd # change references to Qt frameworks
    for L in $QTLIBS ; do # change all lib references in all Qt frameworks
    if [ $L = $I ] ; then continue; fi
    install_name_tool -change $PREFIX/lib/$I.framework/Versions/5/$I\
    @executable_path/../Frameworks/$I.framework/Versions/5/$I\
    $DEST/$BUNDLE.app/Contents/Frameworks/$L.framework/Versions/5/$L
    done
    done
    On s'attaque ensuite aux plugins :

    echo "install_name_tool PLUGINS ...."
    DISTPLUGINS=`cd $DEST/$BUNDLE.app/Contents/PlugIns; ls -1 */*.dylib` # extract all our *.dylib libs
    for P in $DISTPLUGINS ; do # change ID for all *.dylib libs
    install_name_tool -id "@executable_path/../PlugIns/$P" "$DEST/$BUNDLE.app/Contents/PlugIns/$P"
    for L in $QTLIBS ; do # change any reference to Qt in our *.dylib libs
    install_name_tool -change $PREFIX/lib/$L.framework/Versions/5/$L\
    @executable_path/../Frameworks/$L.framework/Versions/5/$L\
    $DEST/$BUNDLE.app/Contents/PlugIns/$P
    done
    done
    SIGNATURE DU BUNDLE


    Ca y est on a un Bundle qui fonctionne :-)

    Une signature est nécessaire pour le MacAppStore. On utilise pour cela l'utilitaire codesign :

    APPLCERT="Developer ID Application: ...."
    DOMAIN="Celui qu'il y a dans votre fichier entitlements"

    codesign -s "$APPLCERT" -v --deep -i "$DOMAIN" --entitlements \
    "$DEST/$BUNDLE.app/Contents/Resources/Zeecrowd.entitlements" \
    "$DEST/$BUNDLE.app/Contents/MacOS/Zeecrowd"
    CONSTRUCTION DU PACKAGE


    productbuild va nous construire un package en le signant (obligatoire). On reprécise le numéro de version de l'application, ainsi que le répertoire de destination lors de l'installation (on le met classiquement dans le repertoire Applications)

    INSTCERT="3rd Party Mac Developer Installer: ......"

    productbuild --version $VERSION --component "$DEST/$BUNDLE.app" /Applications \
    --sign "$INSTCERT" "$DEST/$BUNDLE.pkg"
    Voilà c'est la fin !!!!

    En suivant toutes ces étapes notre application Zeeecrowd a été accepté et se trouve maintenant dans le MacAppStore :cool:
Connectez-vous ou Inscrivez-vous pour répondre.