提交到App Store问题:不支持的体系结构x86


252

因此,我正在尝试使用Shopify API。当我存档应用程序并对其进行验证时,没有任何问题,但是当我将其提交到应用程序商店时,它给了我以下问题。

  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可执行文件。”

4
第一条消息听起来好像是模拟器构建。
菲利普·米尔斯

当我创建要提交的存档时,请在设备选项中选择iOS设备,然后创建存档(如果您要的是)
Saurabh Jain 2015年

2
我同意@PhillipMills。专注于您的第一个错误。为什么您的iOS应用程序中包含x86_64二进制文件?您对构建设置做了一些奇怪的事情...或者您上载了Simulator构建。
斯蒂芬·达林顿

@ pAkY88。我没能。我最近在Shopify API论坛上发布了消息,正在等待回复。如果我碰到一个,肯定会发布一些东西
Saurabh Jain

当我使用Application Loader 3.5上传时,我有此行为
SudoPlz

Answers:


394

问题在于,Buy框架包含针对模拟器(x86_64)和实际设备(ARM)的构建。

当然,您不可以将不支持的体系结构的二进制文件提交到App Store,因此解决方案是在提交最终二进制文件之前“手动”删除不需要的体系结构。

Daniel Kennett提出了一个不错的解决方案,并提供了以下脚本以添加到构建阶段:

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发布的修改后的脚本,因为该脚本存在一些小问题。


6
@ pAkY88我已经在我的Xcode项目中使用此脚本修复了上面提到的App Store问题,但是现在当我去构建时,我遇到了很多致命错误->致命错误:lipo:输入文件(/ ...当指定-extract选项时,Frameworks / Bolts.framework / Bolts)必须是胖文件。任何想法如何解决这一问题?
SamoanProgrammer

52
我认为这很愚蠢:您必须结合使用arm + x86才能允许您的应用程序同时在模拟器和设备上运行,并且必须剥离x86才能提交给应用商店。为什么只要检测到x86,苹果就不会在其末端进行剥离?他们可以提供很多技术方面的理由来捍卫这一点,但由于其根本不友好,因此没有商业方面的理由。
superarts.org

5
@Skoua选择相关目标,然后“构建阶段”并将其放在“嵌入框架”操作之后
Piotr Tobolski

6
上面的脚本很有用,但是没有提到在Xcode中运行脚本的步骤。要运行此脚本,请转到TARGETS->选择Build Phases,然后在Xcode上点击上部标题,在Editor上单击->添加构建阶段->添加运行脚本Build Phases,您将在TARGET的Build Phase部分中获得一列。在这里,您可以复制粘贴上面的脚本并将其成功上传到Appstore。
shashi Gupta

5
无法在Xcode 11.2中使用-有人找到了解决方案吗?
JMIT

178

pAkY88给出的答案是可行的,但是我在https://stackoverflow.com/a/35240555/5272316中遇到了与Mario A Guzman相同的问题:一旦我们切断了未使用的体系结构,我们将无法再运行脚本,因为它试图删除不存在的片,因为xcode不会每次都重新嵌入二进制。想法是-在构建存档时只删除i386和x86_64切片,所以我修改了脚本:

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

如果不为模拟器运行,则此脚本仅从胖二进制文件(如果存在)中删除i386和x86_64切片(这意味着目标文件夹与“ Debug-iphonesimulator”不同)。

抱歉,我不熟悉Shell脚本,因此有人可能会以更优雅的方式编写它。但有效)


1
谢谢你的主意。我只是在while循环内从接受的答案中向代码中添加了一个检查case "${TARGET_BUILD_DIR}" in *"iphonesimulator") echo "Skip simulator target"; continue ;; esac,它的工作就像一个魅力。
Michael Radionov

我正在添加此脚本,TARGET -> Build Phases -> [CP] Embedded Pods Frameworks但是它不起作用,并且我仍然上载到iTunesConnect错误。如何运行此脚本?
PiterPan

2
PiterPan,将其添加为单独的RunScript阶段
Varrry

1
我只是选中了“仅在安装时运行脚本”选项,除了存档外,它都会被跳过。
里维拉

是否在这里提出了所有建议,设法清除了迦太基错误;但需要在未经验证的情况下将其上传到App Store,以获取有关失败原因的一些有用信息。设法解决了这个问题并向前迈进了……
user3069232 2015年

90

如果您使用的是迦太基,则可能会遇到此问题,因为该项目是:

  • 缺少carthage 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。


另外,我最近遇到了这个问题,从使用旧的,预编译的第三方框架版本切换为使用迦太基安装的相同框架的新版本。甚至一旦迦太基完全设置好,我仍然会遇到此错误。对我来说,解决方法是将框架从项目中完全删除,然后重新添加回去。如果您使用的是迦太基,但此答案不能解决您的问题,请尝试这样做。
Ash Ash

1
确实,很棒的帖子。请注意,通常最好的选择是简单地删除所有框架,然后再次开始从Carthage添加所有框架。干杯
Fattie

我正在使用迦太基和元帅,并添加$(SRCROOT)/Carthage/Build/iOS/Marshal.framework了工作
里卡多·穆蒂

在现代iOS中,有99%的时间是问题所在-您只是忘记了复制框架。(现在100%的项目都使用迦太基。)
Fattie

41

我通过从“嵌入式二进制文件”部分(“ Xcode目标->常规”选项卡)中删除了一个框架(出色的SVProgressHUD)解决了ITMS-90080错误。

在此处输入图片说明


5
这个答案应该有更多的支持。我怀疑这是许多使用迦太基的人的根本原​​因。
mm2001

15
如果您尝试嵌入动态框架,则将其删除会为我显示此错误消息:“原因:未找到图片”
electronicix384128

1
这对我有用。您必须从Embedded Binaries中删除框架,然后将其添加到Linked Frameworks and Libraries。另外,您还必须执行其他操作,例如运行在其他答案中找到的脚本。
smileBot

33

如果您正在使用,请Carthage确保您Embed Frameworks Build StepCarthage copy-frameworks


在某些异常情况下(例如:Lottie-iOS框架):

  • 您将像往常一样简单地在“链接库”中拥有它。

  • 但是,必须在“嵌入式​​框架”中显式添加它(尽管这似乎毫无意义,因为当您仅在“嵌入式​​框架”中将其完美使用时,)

  • 把它复制框架

  • 保证复制的框架是经过 “嵌入框架”


这样我的问题。谢谢。
DookieMan

15

使用以下步骤从框架中删除[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. 现在再次打开您的项目,清理,构建和运行以及创建存档...

使用lipo命令删除后,@ mahipal Singh .. 应用程序无法在模拟器中运行。iPhone模拟器缺少x84_64之类的错误。但在真实设备中工作正常。
希塔斯,

这是因为模拟器仅支持调试框架
MAhipal Singh,

14

我将在这里添加2美分(以一种不太吓人的方式:-)。我从供应商那里遇到了很多胖库,由于某些原因,它们由于将它们添加到FrameworksApple记录的目录中而无法正常工作。我们能够使它们起作用的唯一方法是,将其.framekwork右移到项目目录中,Embedded FrameworksLink Binary with Libraries在“构建设置”中手动链接和。这似乎没有任何问题,但是,对于任何胖库,它们都与无关的Simulator体系结构i386 以及体系结构x86_64一起提供arm

检查Fat库上体系结构的快速方法是

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

哪个应该吐这样的输出

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

这确认您需要在iTunesConnect存档上传之前从框架中“删除繁琐”(即i386x86_64),因为该架构不允许这些架构(因为iOS不支持它们)。

现在,这里的所有答案(或至少一些答案)都提供了这些奇妙的运行脚本,我确信它们确实可以很好地运行,但前提是您的框架位于Frameworks目录中。现在,除非您是一个shell脚本迷,否则未经修改的那些脚本将不适用于我在上面说明的场景。但是,有一种非常简单的方法可以从框架中删除i386x86_64架构。

  1. 在项目目录中打开终端。

  2. 将目录直接更改为.framekwork,例如

    cd YourProjectDir/YourProject/YourLibrary.framework

  3. 运行一系列命令,如下所示-

$ 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不会修改输入文件,它只会生成一个文件,因此您必须lipo -removex86_64和运行一次i386。上面的命令通过首先重命名可执行文件,然后最终删除所需的拱门,然后清理剩余的文件来简单地做到这一点。就是这样,您现在应该在Application Loader档案上传到iTunesConnect中看到一个绿色的复选标记。

注意事项:以上步骤仅应在生产构建时执行,因为.framework将剥离模拟器体系结构,因此在模拟器上构建将停止工作(这是预期的)。在开发环境中,.framework由于您希望能够在模拟器和物理设备上进行测试,因此无需从文件中剥离体系结构。如果您的胖图书馆位于Frameworks项目的文件夹中,请查看接受的答案。


针对那些不喜欢脚本的人的简单解决方案。

只需运行上面的命令,足弓的大小就会减小一半。希望有所作为。
showmyroutes '18年

即使我已经部署了脚本以使一切正常运行,但这必须是关于如何解决问题的正确说明。
沙克斯·蒙肯

爱这个答案的性质。简洁明了
Hudi Ilfeld '19

10

即使添加了脚本并更新了几次框架,我也遇到了同样的问题。

确保在xCode中将脚本添加到嵌入之后的末尾。我认为我不小心将脚本移到了嵌入式框架之前。

在此处输入图片说明

注意:我有xCode 9.1


这对我有用。上一年我上一次发布版本时,仅@ pAkY88的脚本就足够了。
RedHotPawn.com

我有同样的问题,这对我有用。确保每次删除和添加框架时都要检查运行脚本的位置(仅在删除了一个框架时才需要)。
Baran Emre

你救了我的日子。只是在嵌入式框架之后添加脚本。
Mayuri R Talaviya

8

为Xcode 10.1更新,以下解决方案对我有用:

只需从嵌入式二进制文件中删除框架,然后将其添加到链接的框架和库中即可。

请参阅下面的屏幕截图;

在此处输入图片说明


1
对我来说有效的解决方案(y)
Alok,

它从链接的框架和库中删除了相同的内容
Ranu Dhurandhar

8

感谢以上所有答案。这是一个使用swift 4.2和5的脚本。用您框架的原始名称替换Your_Framework_Name字符串。

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

谢谢!这对我有用,而被接受的答案却没有。
besserwisser

5

通过稍微修改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

4

我从“构建设置”-“有效体系结构-发行版”中删除了i386和x64_86体系结构,一切正常。

在此处输入图片说明

现在唯一的问题是您不能在SIMULATOR上运行RELEASE构建以进行测试。但是,就像移除拱门一样容易,如果需要,您可以将其重新添加。


1
是的,解决方案。
Ofir Malachi


1

静态(.a)库也可能导致此错误(ITMS-90240)。这是删除多余架构的脚本。在Xcode中,将其添加到Target> BuildPhases>单击+,然后选择Run 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

1

我有同样的问题。添加给定的运行脚本后,即使无法正常工作。这是与Xcode相关的问题。我使用的是Xcode 9.0版,但最新版本是9.2版。

所以我安装了最新的Xcode(9.2),它可以正常工作。


0

您的框架同时包含ARMx86代码,可让您在设备或模拟器中使用它。如果您打算将应用程序提交到App Store,请运行以下脚本以从二进制文件中删除不活动的代码。

1.在“项目浏览器”中选择目标,然后单击项目编辑器顶部的“构建阶段”。

2.从编辑器菜单中,选择添加构建阶段,然后选择添加运行脚本构建阶段(或单击构建阶段编辑器左上角的+按钮)。

3.扩展刚添加的新“运行脚本”构建阶段旁边的显示三角形。在脚本编辑器框中,粘贴以下内容:bash

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


这假定strip-frameworks.sh脚本恰好在那儿……
Codezy

0

这是我用来专门从可执行文件中删除一个框架的体系结构的脚本。

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

将此脚本添加到项目目标的项目“构建阶段”。确保选中以下复选框:“仅在安装时运行脚本”

预览示例脚本的插入位置

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.