ios - las - Problemas de envío a la tienda de aplicaciones: Arquitectura no compatible x86
itunes (17)
Actualizado para Xcode 10.1, la siguiente solución funcionó para mí:
Solo tiene que eliminar el marco de los binarios incrustados y simplemente agregarlo a las bibliotecas y los marcos vinculados.
Consulte la siguiente captura de pantalla;
Así que estoy tratando de usar la API de Shopify. Cuando archivo la aplicación y la valido, no hay problemas, pero cuando la envío a la tienda de aplicaciones, me da los siguientes problemas.
- ERROR ITMS-90087: "Arquitectura no compatible. Su ejecutable contiene arquitectura no compatible ''[x86_64, i386]''".
- ERROR ITMS-90209: "Alineación de segmento inválida. El binario de la aplicación en SJAPP.app/Frameworks/Buy.framework/Buy no tiene la alineación de segmento adecuada. Intente reconstruir la aplicación con la última versión de xcode". (Ya estoy usando la última versión).
- ERROR ITMS-90125: "El binario no es válido. La información de cifrado en el comando de carga LC_ENCRYPTION_INFO falta o no es válida, o el binario ya está cifrado. Parece que este binario no se ha creado con Apple Linker".
- ADVERTENCIA ITMS-90080: "La carga útil ejecutable /..../ Buy.framework no es un ejecutable independiente de la posición. Asegúrese de que su configuración de compilación esté configurada para crear ejecutables PIE".
Agregaré mis 2 centavos aquí (de una manera menos aterradora :-).
Me he encontrado con una gran cantidad de bibliotecas gordas de proveedores que (por alguna razón) no funcionan de la manera normal al agregarlas al directorio de
Frameworks
como lo documenta Apple.
La única forma en que hemos podido hacer que funcionen es arrastrando el
.framekwork
directamente al directorio del proyecto y vinculando los
Embedded Frameworks
y el
Link Binary with Libraries
manualmente en la configuración de compilación.
Sin embargo, esto parece haber funcionado sin problemas, ya que con cualquier biblioteca gorda vienen con las arquitecturas de simulador extrañas
i386
y
x86_64
junto con las arquitecturas de
arm
.
Una forma rápida de verificar las arquitecturas en la biblioteca gorda es
$ cd ''Project_dir/Project''
$ lipo -info ''YourLibrary.framework/YourLibExec`
Lo que debería escupir una salida como esta
Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64
Esto confirma que necesitará "recortar la grasa" (es decir,
i386
y
x86_64
) de su marco antes de la carga de iTunesConnect Archival, que no permite estas arquitecturas (ya que no son compatibles con iOS).
Ahora, todas las respuestas (o al menos algunas de las respuestas) aquí proporcionan estos maravillosos Run Scripts que estoy seguro de que funcionan muy bien, pero solo si su Framework reside en el directorio de
Frameworks
.
Ahora, a menos que seas un adicto al script de shell, esos scripts sin modificaciones no funcionarán para el escenario que explico anteriormente.
Sin embargo, hay una manera muy simple de deshacerse de las arquitecturas
i386
y
x86_64
del marco.
- Abra la terminal en el directorio de su proyecto.
-
Cambie el directorio directamente al
.framekwork
, comocd YourProjectDir/YourProject/YourLibrary.framework
-
Ejecute la serie de comandos como se muestra a continuación:
$ 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
Algunas cosas a tener en cuenta aquí:
lipo -remove
se debe hacer una vez para que cada arquitectura se elimine.
lipo
no modifica el archivo de entrada, solo produce un archivo, por lo que debe ejecutar
lipo -remove
una vez para
x86_64
e
i386
.
Los comandos anteriores simplemente hacen eso primero renombrando el ejecutable y luego eventualmente eliminando los arcos deseados, y luego limpiando los archivos sobrantes.
Y eso es todo, ahora debería ver una marca de verificación verde en la carga del archivo del cargador de aplicaciones en iTunesConnect.
Cosas a tener en cuenta
: los pasos anteriores solo se deben realizar durante la construcción de producción, ya que el
.framework
se eliminará de las arquitecturas del simulador, las construcciones en simuladores dejarán de funcionar (lo que se espera).
En el entorno de desarrollo, no debería haber necesidad de quitar las arquitecturas del archivo
.framework
ya que desea poder realizar pruebas tanto en Simulator como en un dispositivo físico.
Si su biblioteca gorda reside en la carpeta
Frameworks
en el proyecto, mire la respuesta aceptada.
Aquí hay un script que usé para eliminar específicamente la arquitectura de un solo marco del archivo ejecutable.
# 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"
Agregue este script a sus proyectos "Fases de construcción" de su objetivo de proyecto. Asegúrese de marcar la casilla: "Ejecutar script solo al instalar"
El problema es que el marco de compra contiene una compilación tanto para el simulador (x86_64) como para los dispositivos reales (ARM).
Por supuesto, no puede enviar un archivo binario a la App Store para una arquitectura no compatible, por lo que la solución es eliminar "manualmente" las arquitecturas innecesarias del archivo binario final, antes de enviarlo.
Daniel Kennett encontró una buena solución y proporciona este script para agregar a la fase de construcción:
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
Lo usé y funcionó perfectamente.
EDITAR: asegúrese de mirar el script modificado publicado por Varrry, ya que este tiene algunos problemas menores.
Eliminé las arquitecturas i386 y x64_86 de Configuración de compilación - Arquitecturas válidas - Lanzamiento, y todo funcionó bien.
Ahora, el único problema sería que no puede ejecutar una compilación RELEASE con fines de prueba en un SIMULADOR . Pero tan fácilmente como eliminó los arcos, puede agregarlos nuevamente si lo desea.
Elimine [x86_64, i386] del marco utilizando el siguiente paso. [x86_64, i386] se usa para el simulador.
-
Terminal
abierta -
abra la ruta de arrastre de su proyecto del marco respectivo a la Terminal
ejemplo:
cd /Users/MAC/Desktop/MyProject/Alamofire.framework
-
configure su nombre de Framework en el siguiente comando y ejecute
lipo -remove i386 Alamofire -o Alamofire && lipo -remove x86_64 Alamofire -o Alamofire
- Ahora abra su proyecto nuevamente, Clean, Build & Run y Create Archive ...
Este error (ITMS-90240) también puede ser causado por una biblioteca estática (.a). Heres un guión para despojar el exceso de arquitecturas. En Xcode, agregue esto a Target> BuildPhases> Haga clic en + y seleccione Ejecutar script. Luego pegue esto en el cuadro de secuencia de comandos.
El script busca archivos .a, verifica si contiene una arquitectura ofensiva, y luego si crea un nuevo archivo .a sin esa arquitectura.
Para 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
Para 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
Este problema se resolvió para mí modificando ligeramente el script de ejecución de la respuesta de pAky88 y ejecutándolo después de incrustar marcos. También asegúrese de desmarcar la casilla "Ejecutar script solo al instalar".
/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
Gracias a todas las respuestas anteriores. Aquí está el script que trabaja con 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
Si está utilizando Carthage , puede experimentar este problema porque el proyecto es:
-
Falta la fase de compilación de
carthage copy-frameworks
. - O la fase de construcción no incluye todos los marcos (lista incompleta).
Esta acción filtra los marcos a una lista de arquitecturas válidas (code) .
Configuración de la fase de compilación de marcos de copia
Desde el edificio Carthage para los pasos de iOS :
En la pestaña de configuración "Fases de compilación" de los objetivos de su aplicación, haga clic en el icono "+" y seleccione "Nueva fase de ejecución de script". Cree un script de ejecución en el que especifique su shell (por ejemplo, bin / sh), agregue los siguientes contenidos al área de script debajo del shell:
/usr/local/bin/carthage copy-frameworks
y agregue las rutas a los marcos que desea usar en "Archivos de entrada", por ejemplo:
$(SRCROOT)/Carthage/Build/iOS/Box.framework
$(SRCROOT)/Carthage/Build/iOS/Result.framework
$(SRCROOT)/Carthage/Build/iOS/ReactiveCocoa.framework
Esta secuencia de comandos funciona alrededor de un error de envío de la tienda de aplicaciones desencadenado por binarios universales y garantiza que los archivos relacionados con el código de bits y los dSYM necesarios se copien al archivar.
Si está utilizando
Carthage
asegúrese de que el
Build Step
Embed Frameworks
Build Step
esté antes de los
copy-frameworks
Carthage
En algunos casos inusuales (ejemplo: marco Lottie-iOS):
-
lo tendrá simplemente en "Biblioteca de enlaces" como de costumbre.
-
Sin embargo , también debe agregarlo explícitamente en "Embed Frameworks" (aunque parezca inútil, ya que funciona perfectamente cuando solo lo tiene en "Embed Frameworks"),
-
y ponerlo en marcos de copia
-
y asegúrese de que copy-frameworks esté después de "Embed Frameworks"
Su marco contiene código
ARM
y
x86
, que le permite usarlo en un dispositivo o en el simulador.
Si tiene la intención de enviar su aplicación a la App Store, ejecute el siguiente script para quitar el código inactivo del binario.
1. Seleccione su objetivo en el Navegador de proyectos y haga clic en Crear fases en la parte superior del editor de proyectos.
2.En el menú Editor, seleccione Agregar fase de compilación, luego Agregar fase de compilación de ejecución de script (o haga clic en el botón + en la esquina superior izquierda del editor de fases de compilación).
3. Expanda el triángulo de revelación junto a la nueva fase de compilación Ejecutar script que se acaba de agregar. En el cuadro del editor de script, pegue lo siguiente: bash
$ {BUILT_PRODUCTS_DIR} / $ {FRAMEWORKS_FOLDER_PATH} / "YourframeworkName.framework" /strip-frameworks.sh
Tuve el mismo problema Incluso no funcionaba después de agregar el Run Script dado. Era un problema relacionado con Xcode. Estaba usando la versión 9.0 de Xcode pero la última versión era la 9.2.
Así que instalé el último Xcode (9.2) y funcionó.
la solución simple que funcionó para mí fue
1- eliminar el marco de los marcos incrustados.
2- agrega el marco como un marco vinculado
¡hecho!
Answer dada por pAkY88 funciona, pero enfrenté el mismo problema que Mario A Guzman en https://.com/a/35240555/5272316 : una vez que cortamos las arquitecturas no utilizadas, ya no podemos ejecutar el script, ya que trata de eliminar rebanadas no existentes, porque xcode no vuelve a incrustar binarios cada vez. La idea era: simplemente elimine los segmentos i386 y x86_64 al compilar para el archivo comprimido, así que modifiqué el 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
Este script simplemente elimina los segmentos i386 y x86_64 del binario gordo (si existen) si no se ejecuta para el simulador (eso significa que la carpeta de destino no es como "Debug-iphonesimulator").
Lo siento, no estoy familiarizado con los scripts de shell, por lo que puede ser que alguien pueda escribirlo de una manera más elegante. Pero funciona)