Отправить в App Store: Неподдерживаемая архитектура x86

Поэтому я пытаюсь использовать API Shopify. Когда я архивирую приложение и проверяю его, проблем не возникает, но когда я отправляю его в магазин приложений, возникают следующие проблемы.

  1. ОШИБКА ITMS-90087: "Неподдерживаемая архитектура. Ваш исполняемый файл содержит неподдерживаемую архитектуру" [x86_64, i386] "."
  2. ОШИБКА ITMS-90209: "Неверное выравнивание сегмента. Двоичный файл приложения на SJAPP.app/Frameworks/Buy.framework/Buy не имеет правильного выравнивания сегмента. Попробуйте перестроить приложение с последней версией xcode". (Я уже использую последнюю версию.)
  3. ОШИБКА ITMS-90125: "Двоичный файл недействителен. Информация шифрования в команде загрузки LC_ENCRYPTION_INFO либо отсутствует, либо недействительна, либо двоичный файл уже зашифрован. Похоже, этот двоичный файл не был создан с помощью Apple Linker".
  4. ПРЕДУПРЕЖДЕНИЕ ITMS-90080: "Исполняемая полезная нагрузка /..../Buy.framework не является независимой от позиции исполняемой программой. Пожалуйста, убедитесь, что настройки сборки сконфигурированы для создания исполняемых файлов PIE".

Ответ 1

Проблема состоит в том, что платформа Buy содержит сборку как для симулятора (x86_64), так и для реальных устройств (ARM).

Конечно, вам не разрешено отправлять в App Store двоичный файл для неподдерживаемой архитектуры, поэтому решение состоит в том, чтобы "вручную" удалить ненужные архитектуры из окончательного двоичного файла перед его отправкой.

Даниэль Кеннетт предложил отличное решение и предоставляет этот сценарий для добавления на этапе сборки:

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

Я использовал это, и это работало отлично.

РЕДАКТИРОВАТЬ: убедитесь, что вы посмотрите на измененный скрипт, опубликованный Varrry, так как у этого есть некоторые незначительные проблемы.

Ответ 2

Ответ, данный pAkY88, но я столкнулся с той же проблемой, что и Марио А Гузман в fooobar.com/questions/41720/...: как только мы отключили неиспользуемые архитектуры, мы больше не можем запускать script, так как он пытается удалить не существующие фрагменты, потому что xcode не повторно встраивает двоичные файлы каждый раз. Идея была - просто удалите куски i386 и x86_64 при создании архива, поэтому я изменил 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 archs if location is not simulator 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

Этот script просто удаляет фрагменты i386 и x86_64 из живого двоичного файла (если они существуют), если он работает не для симулятора (это означает, что папка назначения не похожа на "Debug-iphonesimulator" ).

Извините, я не знаком с сценариями оболочки, поэтому может быть кто-то может написать более элегантный способ. Но он работает)

Ответ 3

Если вы используете Карфаген, вы можете столкнуться с этой проблемой, потому что проект:

  • Отсутствует фаза сборки carthage copy-frameworks.
  • Или фаза сборки не включает в себя все фреймворки (неполный список).

Это действие фильтрует фреймворки в список допустимых архитектур (код).

Настройка фазы сборки copy-frameworks

Из здания Карфагена для шагов iOS:

На вкладке настроек цели приложения "Фазы сборки" нажмите значок "+" и выберите "Фаза запуска нового скрипта". Создайте сценарий запуска, в котором вы указываете свою оболочку (например, bin/sh), добавьте следующее содержимое в область сценария под оболочкой:

/usr/local/bin/carthage copy-frameworks

и добавьте пути к фреймворкам, которые вы хотите использовать в разделе "Входные файлы", например:

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

Этот сценарий работает вокруг ошибки отправки в App Store, вызванной универсальными двоичными файлами, и обеспечивает копирование необходимых файлов, связанных с битовым кодом, и файлов dSYM при архивировании.

Ответ 4

Я разрешил ошибку ITMS-90080, удалив фреймворк (отличный SVProgressHUD) из раздела Embedded Binaries (цель Xcode → General).

введите описание изображения здесь

Ответ 5

Если вы используете Carthage, убедитесь, что ваш Embed Frameworks Build Step находится перед Carthage copy-frameworks


В некоторых необычных случаях (пример: Lottie-iOS framework):

  • вы будете иметь его просто в "Библиотеке ссылок", как обычно.

  • Однако вы должны также явно добавлять его в "Embed Framework" (хотя это кажется бессмысленным, поскольку он отлично работает, когда вы его используете только в "Вставить рамки" ),

  • и поместите его в рамки копирования

  • и убедитесь, что copy-framework после "Вставить рамки"

Ответ 6

Я добавлю свои 2 цента здесь (менее страшно :-). Я встречал довольно много толстых библиотек от поставщиков, которые (по какой-то причине) не работают обычным образом, добавляя их в каталог Frameworks как описано в Apple. Единственный способ заставить их работать - это .framekwork прямо в каталог проекта и вручную связать Embedded Frameworks и связать .framekwork Link Binary with Libraries в настройках сборки. Похоже, что это сработало без каких-либо проблем, так как с любой толстой библиотекой они поставляются с посторонними архитектурами Simulator i386 и x86_64 вместе с архитектурами arm.

Быстрый способ проверить архитектуру в толстой библиотеке

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

Который должен выплевывать вывод примерно так

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

Это подтверждает, что вам нужно будет "обрезать жир" (а именно i386 и x86_64) из вашей инфраструктуры до загрузки iTunesConnect Archival, что не позволяет использовать эти архитектуры (так как они не поддерживаются для iOS).

Теперь все ответы (или, по крайней мере, некоторые из ответов) здесь предоставляют эти замечательные Run Scripts, которые, я уверен, работают действительно хорошо, но только если ваш Framework находится в каталоге Frameworks. Теперь, если вы не любитель сценариев оболочки, эти сценарии без изменений не будут работать для сценария, который я объяснил выше. Однако существует очень простой способ избавиться от i386 и x86_64 из инфраструктуры.

  1. Откройте терминал в каталоге вашего проекта.
  2. Изменить каталог прямо в .framekwork, как

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. Запустите серию команд, как показано below-

    $ 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

Здесь нужно отметить несколько вещей - lipo -remove нужно сделать один раз для каждой lipo -remove архитектуры. lipo не изменяет входной файл, он только создает файл, поэтому вам нужно один раз запустить lipo -remove для x86_64 и i386. Приведенные выше команды просто делают это, сначала переименовывая исполняемый файл, а затем, в конечном счете, удаляя нужные архивы, а затем убирая оставшиеся файлы. И вот, теперь вы должны увидеть зеленую галочку в загрузке архива приложения-загрузчика в iTunesConnect.

Что нужно иметь в виду: вышеупомянутые шаги должны быть выполнены только во время сборки продукта, так как .framework будет .framework из архитектур симулятора, сборки на симуляторах перестанут работать (что ожидается). В среде разработки не должно быть необходимости .framework архитектуры из файла .framework поскольку вы хотите иметь возможность проводить тестирование как на симуляторе, так и на физическом устройстве. Если ваша толстая библиотека находится в папке Frameworks в проекте, пожалуйста, посмотрите на принятый ответ.

Ответ 7

Удалите [x86_64, i386] из каркаса, используя шаг ниже. [x86_64, i386] используется для симулятора.

  1. Открытый Terminal

  2. откройте путь перетаскивания вашего проекта соответствующей платформы в терминал

    пример: cd/Users/MAC/Desktop/MyProject/Alamofire.framework

  3. установите имя вашей платформы в приведенной ниже команде и запустите

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

  1. Теперь снова откройте свой проект, очистите, создайте и запустите и создайте архив...

Ответ 8

У меня была такая же проблема даже после добавления скрипта и обновления фреймворка несколько раз.

Убедитесь, что в xCode скрипт добавлен в конце после встраивания. Я думаю, что я случайно переместил скрипт перед встроенным фреймворком.

enter image description here

Примечание: у меня есть xCode 9.1

Ответ 9

  Обновлено для Xcode 10.1, ниже решение работает для меня:

Вам просто нужно удалить фреймворк из Embedded Binaries и просто добавить его в связанные фреймворки и библиотеки.

Смотрите скриншот ниже;

enter image description here

Ответ 10

Эта проблема была решена для меня, слегка изменив скрипт запуска из ответа pAky88 и выполнив его после встраивания фреймворков. Также обязательно снимите флажок "Запускать скрипт только при установке".

/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

Ответ 11

Я удалил архитектуры i386 и x64_86 из настроек сборки - Valid Architectures - Release, и все сработало нормально.

введите описание изображения здесь

Теперь единственная проблема заключается в том, что вы не можете запустить сборку RELEASE для тестирования на SIMULATOR. Но так же легко, как вы удалили арки, вы можете добавить их обратно, если хотите.

Ответ 12

простое решение, которое работало для меня, было

1- удалить каркас из встроенных каркасов.

2- добавить структуру как связанную структуру

сделанный!

Ответ 13

Спасибо всем выше ответам. Вот скрипт, работающий с swift 4.2 и 5

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

Ответ 14

Эта ошибка (ITMS-90240) также может быть вызвана статической (.a) библиотекой. heres a script, чтобы удалить лишние архитектуры. В Xcode добавьте это в Target > BuildPhases > Нажмите + и выберите Run Script. Затем вставьте это в поле script.

script выполняет поиск файлов .a, проверяет, содержит ли он оскорбительную архитектуру, а затем делает новый .a файл без этой архитектуры.

Для 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

Для 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

Ответ 15

У меня была такая же проблема. Даже он не работал после добавления данного Run Script. Это была проблема, связанная с Xcode. Я использовал версию Xcode 9.0, но последняя версия была 9.2.

Поэтому я установил последнюю версию Xcode (9.2), и она заработала.

Ответ 16

Ваш фреймворк содержит код как ARM и x86, что позволяет использовать его на устройстве или в симуляторе. Если вы намереваетесь отправить свое приложение в App Store, запустите следующий сценарий, чтобы удалить неактивный код из двоичного файла.

1.Выберите цель в Навигаторе проекта и нажмите "Фазы сборки" в верхней части редактора проекта.

2. В меню "Редактор" выберите "Добавить этап сборки", затем "Добавить этап сборки сценария запуска" (или нажмите кнопку "+" в верхнем левом углу редактора этапов сборки).

3.Разверните раскрывающий треугольник рядом с новой только что добавленной фазой построения Run Script. В окне редактора сценариев вставьте следующее: bash

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

Ответ 17

Вот скрипт, который я использовал, чтобы специально удалить только одну архитектуру фреймворка из исполняемого файла.

# 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"

Добавьте этот скрипт в ваши проекты "Build Phases" вашего проекта. Обязательно установите флажок: "Запускать скрипт только при установке"

Preview of where to insert sample script