web-dev-qa-db-fra.com

Soumettre à l'App Store: Architecture non prise en charge x86

J'essaie donc d'utiliser l'API Shopify. Lorsque j'archive l'application et la valide, il n'y a aucun problème, mais lorsque je la soumets à l'App Store, les problèmes suivants me sont signalés.

  1. ERREUR ITMS-90087: "Architecture non prise en charge. Votre exécutable contient une architecture non prise en charge '[x86_64, i386]'."
  2. ERREUR ITMS-90209: "Alignement de segment non valide. Le binaire de l'application sur SJAPP.app/Frameworks/Buy.framework/Buy ne dispose pas d'un alignement de segment correct. Essayez de reconstruire l'application avec la dernière version de xcode." (J'utilise déjà la dernière version.)
  3. ERREUR ITMS-90125: "Le fichier binaire n'est pas valide. Les informations de chiffrement de la commande de chargement LC_ENCRYPTION_INFO sont manquantes ou non valides, ou le fichier binaire est déjà chiffré. Ce fichier binaire ne semble pas avoir été créé avec l'éditeur de liens d'Apple."
  4. AVERTISSEMENT ITMS-90080: "L'exécutable Payload /..../ Buy.framework n'est pas un exécutable indépendant du poste. Assurez-vous que vos paramètres de construction sont configurés pour créer des exécutables PIE."
220
Saurabh Jain

Le problème est que la structure Buy contient une construction pour le simulateur (x86_64) et les périphériques réels (ARM).

Bien sûr, vous n'êtes pas autorisé à soumettre à l'App Store un fichier binaire pour une architecture non prise en charge. La solution consiste donc à supprimer "manuellement" les architectures inutiles du fichier binaire final avant de le soumettre.

Daniel Kennett a proposé ne solution de Nice et fournit ce script à ajouter à la phase de construction:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
    FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
    FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
    echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"

    EXTRACTED_ARCHS=()

    for Arch in $ARCHS
    do
        echo "Extracting $Arch from $FRAMEWORK_EXECUTABLE_NAME"
        lipo -extract "$Arch" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$Arch"
        EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$Arch")
    done

    echo "Merging extracted architectures: ${ARCHS}"
    lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
    rm "${EXTRACTED_ARCHS[@]}"

    echo "Replacing original executable with thinned version"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"

done

Je l'ai utilisé et cela a fonctionné parfaitement.

EDIT: assurez-vous de regarder le script modifié posté par Varrry, car celui-ci présente quelques problèmes mineurs.

362
pAkY88

Réponse donné par pAkY88 fonctionne, mais j'ai rencontré le même problème que Mario A Guzman dans https://stackoverflow.com/a/35240555/5272316 : une fois que nous avons coupé inutilisé architectures nous ne pouvons plus exécuter de script car il essaie de supprimer des tranches non existantes, car xcode ne ré-incorpore pas binaire à chaque fois. L'idée était - il suffit de supprimer les tranches i386 et x86_64 lors de la création de l'archive, j'ai donc modifié le script:

echo "Target architectures: $ARCHS"

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

FRAMEWORK_TMP_PATH="$FRAMEWORK_EXECUTABLE_PATH-tmp"

# remove simulator's archs if location is not simulator's directory
case "${TARGET_BUILD_DIR}" in
*"iphonesimulator")
    echo "No need to remove archs"
    ;;
*)
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_Arch "i386") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "i386" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "i386 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    if $(lipo "$FRAMEWORK_EXECUTABLE_PATH" -verify_Arch "x86_64") ; then
    lipo -output "$FRAMEWORK_TMP_PATH" -remove "x86_64" "$FRAMEWORK_EXECUTABLE_PATH"
    echo "x86_64 architecture removed"
    rm "$FRAMEWORK_EXECUTABLE_PATH"
    mv "$FRAMEWORK_TMP_PATH" "$FRAMEWORK_EXECUTABLE_PATH"
    fi
    ;;
esac

echo "Completed for executable $FRAMEWORK_EXECUTABLE_PATH"
echo $(lipo -info "$FRAMEWORK_EXECUTABLE_PATH")

done

Ce script supprime simplement les tranches i386 et x86_64 du fat binary (si elles existent) si elles ne fonctionnent pas pour le simulateur (cela signifie que le dossier de destination ne ressemble pas à "Debug-iphonesimulator").

Désolé, je ne connais pas bien les scripts Shell, alors quelqu'un pourrait peut-être l'écrire de manière plus élégante. Mais ça marche)

141
Varrry

Si vous utilisez Carthage , vous pouvez rencontrer ce problème car le projet est:

  • Il manque la phase de construction carthage copy-frameworks.
  • Ou la phase de construction n'inclut pas tous les cadres (liste incomplète).

Cette action filtre les frameworks en une liste d'architectures valides (code) .

Mise en place de la phase de construction des copy-frameworks

Depuis le bâtiment Carthage pour les étapes iOS :

Dans l’onglet Paramètres "Construire les phases" de vos cibles d’application, cliquez sur l’icône "+", puis choisissez "Nouvelle phase de script d’exécution". Créez un script d'exécution dans lequel vous spécifiez votre shell (par exemple, bin/sh), ajoutez le contenu suivant à la zone de script située sous le shell:

/usr/local/bin/carthage copy-frameworks

et ajoutez les chemins aux frameworks que vous souhaitez utiliser sous "Fichiers d’entrée", par exemple:

$(SRCROOT)/Carthage/Build/iOS/Box.framework$(SRCROOT)/Carthage/Build/iOS/Result.framework$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework

Ce script contourne un bogue de soumission de l'App Store déclenché par des fichiers binaires universels et garantit que les fichiers liés au bitcode et les dSYM nécessaires sont copiés lors de l'archivage.

86
odlp

J'ai résolu l'erreur ITMS-90080 en supprimant un cadre (l'excellent SVProgressHUD) de la section Binaires incorporés (cible Xcode -> onglet Général).

enter image description here

39
Bart van Kuik

Si vous utilisez Carthage assurez-vous que votre Embed FrameworksBuild Step est avant le Carthagecopy-frameworks


Dans certains cas inhabituels (exemple: framework Lottie-iOS):

  • vous l'aurez tout simplement dans "Link Library" comme d'habitude.

  • Cependant vous devez aussi l'ajouter explicitement dans "Frameworks intégrés" (même si cela semble inutile, car cela fonctionne parfaitement si vous ne l'avez que dans "Frameworks intégrés"),

  • et le mettre dans des cadres de copie

  • et s'assurent que les cadres de copie sont après "Cadres intégrés"

31
Maciej Swic

J'ajouterai mes 2 centimes ici (d'une manière moins effrayante :-). J'ai rencontré un grand nombre de bibliothèques fat de fournisseurs qui (pour une raison quelconque) ne fonctionnent pas normalement en les ajoutant au répertoire Frameworks tel que documenté par Apple. La seule façon de les faire fonctionner consiste à extraire le .framekwork dans le répertoire du projet et à lier manuellement les Embedded Frameworks et Link Binary with Libraries dans les paramètres de construction. Cela semble avoir fonctionné sans problème, cependant, comme pour toute bibliothèque Fat, ils viennent avec les architectures de simulateur superflues i386 et x86_64 avec les architectures arm.

Un moyen rapide de vérifier les architectures de la grosse bibliothèque est

$ cd 'Project_dir/Project'
$ lipo -info 'YourLibrary.framework/YourLibExec`

Qui devrait cracher une sortie quelque chose comme ça

Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64

Cela confirme que vous aurez besoin de "couper le gras" (à savoir i386 & x86_64) à partir de votre infrastructure avant le téléchargement iTunesConnect Archival, ce qui n'autorise pas ces architectures (car elles ne sont pas prises en charge pour iOS). .

Maintenant, toutes les réponses (ou au moins certaines des réponses) fournissent ici ces merveilleux scripts d’exécution qui, j'en suis sûr, fonctionnent très bien, mais uniquement si votre Framework réside dans le répertoire Frameworks. Maintenant, sauf si vous êtes un junkie de scripts Shell, ces scripts sans modifications ne fonctionneront pas pour le scénario que j'explique ci-dessus. Cependant, il existe un moyen très simple de supprimer les architectures i386 & x86_64 du framework.

  1. Ouvrez le terminal dans le répertoire de votre projet.
  2. Changer de répertoire directement dans le .framekwork, comme

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. Exécutez la série de commandes comme indiqué ci-dessous.

    $ mv YourLibrary YourLibrary_all_archs

    $ lipo -remove x86_64 YourLibrary_all_archs -o YourLibrary_some_archs

    $ lipo -remove i386 YourLibrary_some_archs -o YourLibrary

    $ rm YourLibrary_all_archs YourLibrary_some_archs

Quelques points à noter ici - lipo -remove doit être effectué une fois pour chaque architecture à supprimer. lipo ne modifie pas le fichier d'entrée, il ne produit qu'un fichier. Vous devez donc exécuter lipo -remove une fois pour x86_64 et i386. Les commandes ci-dessus font simplement cela en renommant d'abord l'exécutable puis en supprimant éventuellement les archives souhaitées, puis en nettoyant les fichiers restants. Et voilà, vous devriez maintenant voir une coche verte lors du téléchargement d’Application Loader Archival vers iTunesConnect.

Points à garder à l'esprit: Les étapes ci-dessus ne doivent être effectuées que pendant la construction de la production, puisque le .framework sera supprimé des architectures de simulateur, les constructions sur simulateurs cesseront de fonctionner (ce qui est prévu). . En environnement de développement, il ne devrait pas être nécessaire de supprimer les architectures du fichier .framework, car vous souhaitez pouvoir tester à la fois sur Simulator et sur un périphérique physique. Si votre grosse bibliothèque réside dans le dossier Frameworks du projet, veuillez regarder la réponse acceptée.

10
Annjawn

J'ai eu le même problème, même après avoir ajouté le script et mis à jour le framework plusieurs fois.

Assurez-vous que dans xCode le script est ajouté à la fin, après l’intégration. Je pense avoir accidentellement déplacé le script avant la structure intégrée.

enter image description here

Note: j'ai xCode 9.1

9
Florin Dobre

Supprimez [x86_64, i386] du cadre à l'aide de l'étape ci-dessous. [x86_64, i386] est utilisé pour le simulateur.

  1. Ouvrir Terminal

  2. ouvrez le chemin de glissement de votre projet du framework respectif vers Terminal

    exemple: cd /Users/MAC/Desktop/MyProject/Alamofire.framework

  3. définir votre nom de cadre dans la commande ci-dessous et exécuter

lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire

  1. Maintenant, ouvrez votre projet à nouveau, Nettoyer, Construire & Exécuter et Créer une archive ...
9
MAhipal Singh

Ce problème a été résolu en modifiant légèrement le script d'exécution à partir de la réponse de pAky88 et en l'exécutant après l'intégration de cadres. Veillez également à décocher la case "Exécuter le script uniquement lors de l'installation".

/usr/local/bin/carthage copy-frameworks

#!/usr/bin/env bash

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"

# This script loops through the frameworks embedded in the application and
# removes unused architectures.
find "$APP_PATH" -name '*.framework' -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"

if [ ! -f "${FRAMEWORK_EXECUTABLE_PATH}" ]; then
continue
fi

if xcrun lipo -info "${FRAMEWORK_EXECUTABLE_PATH}" | grep --silent "Non-fat"; then
echo "Framework non-fat, skipping: $FRAMEWORK_EXECUTABLE_NAME"
continue
fi

echo "Thinning framework $FRAMEWORK_EXECUTABLE_NAME"

EXTRACTED_ARCHS=()

for Arch in $ARCHS
do
echo "Extracting $Arch from $FRAMEWORK_EXECUTABLE_NAME"
xcrun lipo -extract "$Arch" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$Arch"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$Arch")
done

echo "Merging extracted architectures: ${ARCHS}"
xcrun lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"

echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
4
objectively C

Mise à jour pour Xcode 10.1, la solution ci-dessous a fonctionné pour moi:

Vous devez juste supprimer la structure des fichiers binaires incorporés et l'ajouter aux cadres et bibliothèques liés.

Reportez-vous ci-dessous capture d'écran;

enter image description here

4
Kiran jadhav

J'ai supprimé les architectures i386 et x64_86 de Build Settings - Valid Architectures - Release, et tout a bien fonctionné.

enter image description here

Maintenant, le seul problème serait que vous ne pouvez pas exécuter une version RELEASE à des fins de test sur un SIMULATEUR. Mais aussi facilement que vous avez supprimé les arches, vous pouvez les rajouter si vous le souhaitez.

3
Mihai Erős

la solution simple qui a fonctionné pour moi était

1- Retirez le framework des frameworks intégrés.

2- ajouter le cadre en tant que cadre lié

terminé!

2
DeyaEldeen

Merci à toutes les réponses ci-dessus. Voici un script fonctionnant avec Swift 4.2

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
FRAMEWORK_NAME="Your_Framework_Name.framework"
# Check if Framework is present.
FRAMEWORK_LOCATION=$(find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d)
if [ -z $FRAMEWORK_LOCATION ]; then
echo "Couldn't find Your_Framework_Name.framework in $APP_PATH. Make sure 'Embed Frameworks' build phase is listed before the 'Strip Unused Architectures' build phase."
exit 1
fi
# This script strips unused architectures
find "$APP_PATH" -name "$FRAMEWORK_NAME" -type d | while read -r FRAMEWORK
do
FRAMEWORK_EXECUTABLE_NAME=$(defaults read "$FRAMEWORK/Info.plist" CFBundleExecutable)
FRAMEWORK_EXECUTABLE_PATH="$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME"
echo "Executable is $FRAMEWORK_EXECUTABLE_PATH"
EXTRACTED_ARCHS=()
for Arch in $ARCHS
do
echo "Extracting $Arch from $FRAMEWORK_EXECUTABLE_NAME"
lipo -extract "$Arch" "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH-$Arch"
EXTRACTED_ARCHS+=("$FRAMEWORK_EXECUTABLE_PATH-$Arch")
done
echo "Merging extracted architectures: ${ARCHS}"
lipo -o "$FRAMEWORK_EXECUTABLE_PATH-merged" -create "${EXTRACTED_ARCHS[@]}"
rm "${EXTRACTED_ARCHS[@]}"
echo "Replacing original executable with thinned version"
rm "$FRAMEWORK_EXECUTABLE_PATH"
mv "$FRAMEWORK_EXECUTABLE_PATH-merged" "$FRAMEWORK_EXECUTABLE_PATH"
done
1
GSK

Cette erreur (ITMS-90240) peut également être provoquée par une bibliothèque statique (.a). Heres un script pour dépouiller les architectures en excès. Dans Xcode, ajoutez ceci à Target> BuildPhases> Cliquez sur le + et sélectionnez Exécuter le script. Collez ensuite ceci dans la boîte de script.

Le script recherche les fichiers .a, vérifie s'il contient une architecture fautive, puis crée un nouveau fichier .a sans cette architecture.

Pour macOS:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="armv7 armv7s arm64"
for t in $STRIPARCHS
do

if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
    find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi

done

exit 0

Pour iOS:

APP_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}"
STRIPARCHS="x86_64 i386"
for t in $STRIPARCHS
do

if find "$APP_PATH" -name '*.a' -exec lipo -info {} \; | grep $t ; then
    find "$APP_PATH" -name '*.a' -exec lipo -remove $t {} -output {}2 \; -exec rm {} \; -exec mv {}2 {} \; ;
fi

done

exit 0
1
A.Badger

J'ai eu le même problème. Même cela ne fonctionnait pas après l'ajout du script d'exécution donné. C'était un problème lié à Xcode. J'utilisais la version 9.0 de Xcode, mais la dernière version était la 9.2.

J'ai donc installé le dernier Xcode (9.2) et cela a fonctionné.

1
Mahesh

Votre infrastructure contient à la fois le code ARM et x86, ce qui vous permet de l'utiliser sur un périphérique ou dans le simulateur. Si vous avez l'intention de soumettre votre application sur l'App Store, exécutez le script suivant pour supprimer le code inactif du fichier binaire.

1.Sélectionnez votre cible dans le navigateur de projet et cliquez sur Construire les phases en haut de l'éditeur de projet.

2.Dans le menu Editeur, sélectionnez Ajouter une phase de construction, puis Ajouter une phase de construction du script d'exécution (ou cliquez sur le bouton + dans le coin supérieur gauche de l'éditeur de phases de construction).

3. Développez le triangle d'affichage en regard de la nouvelle phase de construction du script d'exécution qui vient d'être ajoutée. Dans la zone de l'éditeur de script, collez ce qui suit: bash

$ {BUILT_PRODUCTS_DIR}/$ {FRAMEWORKS_FOLDER_PATH}/"YourframeworkName.framework"/strip-frameworks.sh

0
Georgekutty Joy

Voici un script que j'avais l'habitude de supprimer spécifiquement de l'architecture d'un seul framework du fichier exécutable.

# Remove unused Framework architecture from "YourApp" framework.

FRAMEWORK_EXECUTABLE_PATH="${TARGET_BUILD_DIR}/${WRAPPER_NAME}/Frameworks/YourApp.framework/YourApp"

echo "$FRAMEWORK_EXECUTABLE_PATH"

cp "$FRAMEWORK_EXECUTABLE_PATH" "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"

echo "Executing following command to remove x86_64 Arch from YourApp framework executable"
echo "lipo -remove x86_64 \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"${FRAMEWORK_EXECUTABLE_PATH}_X86_64\""

lipo -remove x86_64 "${FRAMEWORK_EXECUTABLE_PATH}_X86_64" -o "$FRAMEWORK_EXECUTABLE_PATH"

rm "${FRAMEWORK_EXECUTABLE_PATH}_X86_64"

Ajoutez ce script à vos projets "Construire des phases" de la cible de votre projet. Assurez-vous de cocher la case: "Exécuter le script uniquement lors de l'installation"

Preview of where to insert sample script

0
keaplogik