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

Sau*_*ain 232 xcode ios

所以我想尝试使用shopify API.当我存档应用程序并验证它然后没有问题但是当我将它提交到应用商店时它会给我以下问题.

  1. 错误ITMS-90087:"不支持的体系结构.您的可执行文件包含不受支持的体系结构'[x86_64,i386]'."
  2. ERROR ITMS-90209:"无效的段对齐.SJAPP.app/Frameworks/Buy.framework/Buy上的应用程序二进制文件没有正确的段对齐.尝试使用最新的xcode版本重建应用程序." (我已经在使用最新版本了.)
  3. 错误ITMS-90125:"二进制文件无效.LC_ENCRYPTION_INFO加载命令中的加密信息丢失或无效,或者二进制文件已加密.此二进制文件似乎不是使用Apple的链接器构建的."
  4. 警告ITMS-90080:"可执行的有效负载/ $/Buy.framework不是位置无关的可执行文件.请确保将您的构建设置配置为创建PIE可执行文件."

pAk*_*Y88 373

问题是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
Run Code Online (Sandbox Code Playgroud)

我用过它并且效果很好.

编辑:确保你看看Varrry发布的修改过的脚本,因为这个有一些小问题.

  • 我认为这很愚蠢:你必须结合arm + x86来允许你的应用在模拟器和设备上运行,并且必须剥离x86以提交到app store.只要检测到x86,为什么Apple不会在它们的端部进行剥离?他们可以帮助很多技术原因来捍卫这一点,但没有任何商业原因,因为它根本不是用户友好的. (42认同)
  • @ pAkY88我在我的Xcode项目中使用了这个脚本来修复上面提到的App Store问题,但是现在当我去Build时,我有很多致命错误 - >致命错误:lipo:输入文件(/ ...当指定-extract选项时,Frameworks/Bolts.framework/Bolts)必须是胖文件.任何想法如何解决这一问题? (6认同)
  • @Skoua选择相关目标,然后选择"Build Phases"并将其放在"Embed Frameworks"操作之后 (4认同)
  • 上面的脚本很有用,但没有提及在Xcode中运行脚本的步骤。要运行此脚本,请转到TARGETS->选择Build Phases,然后在Xcode上的上部标题上点击编辑器->添加构建阶段->添加运行脚本Build Phases,您将在TARGET的Build Phase部分中获得一列。在这里,您可以复制粘贴上面的脚本并将其成功上传到Appstore。 (4认同)
  • 升级到xcode 11.2时停止工作。 (3认同)
  • 无法在Xcode 11.2中使用-有人找到了解决方案吗? (2认同)
  • 嗨朋友们,上面提到的答案的脚本是正确的,棘手的部分是放置它的位置,它适用于使用带条和切片的存档上传应用程序。编辑方案 -> 存档 -> 打开下拉菜单 -> 发布操作 -> + 添加新脚本 -> 复制并粘贴享受。:) (2认同)
  • @pAkY88 重要提示:现在在新的 M1 mac 中,模拟器架构是 arm64,因此此脚本删除了新的 xcframeworks 和框架中的所有内容。这就是为什么IPA总是安装失败的原因。!!!!!警告!!!!! (2认同)

Var*_*rry 155

答案由pAkY88给出的作品,但我在面对同样的问题马里奥·古斯曼/sf/answers/2466838881/:一旦我们切断了,我们不能运行任何脚本更因为它会尝试删除未使用的架构不是现有的切片,因为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
Run Code Online (Sandbox Code Playgroud)

如果不是为模拟器运行(这意味着目标文件夹不像"Debug-iphonesimulator"),这个脚本只是从胖二进制文件(如果存在)中删除i386和x86_64片.

对不起,我不熟悉shell脚本,所以可能有人可以用更优雅的方式编写它.但它有效)

  • PiterPan,将其添加为单独的RunScript阶段 (2认同)

odl*_*dlp 87

如果您使用的是Carthage,那么您可能会遇到此问题,因为该项目是:

  • 缺少carthage copy-frameworks构建阶段.
  • 或者构建阶段不包括所有框架(不完整列表).

此操作将框架过滤为有效体系结构(代码)列表.

设置复制框架构建阶段

来自Carthage建筑的iOS步骤:

在应用程序目标的"构建阶段"设置选项卡上,单击"+"图标并选择"新建运行脚本阶段".创建一个运行脚本,在其中指定shell(例如:bin/sh),将以下内容添加到shell下面的脚本区域:

/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提交错误,并确保在归档时复制必要的bitcode相关文件和dSYM.


Bar*_*uik 39

我通过从嵌入式二进制文件部分(Xcode目标 - >常规选项卡)中删除框架(优秀的SVProgressHUD)来解决错误ITMS-90080.

在此输入图像描述

  • 如果您尝试嵌入动态框架然后删除它会导致此错误消息:"原因:图像未找到" (12认同)
  • 这个答案应该有更多的赞成.我怀疑这是许多人使用迦太基的根本原因. (5认同)

Mac*_*wic 32

如果你正在使用,请Carthage确保你Embed Frameworks Build Step在...之前Carthage copy-frameworks


在一些不寻常的情况下(例如:Lottie-iOS框架):

  • 你会照常在"链接库"中使用它.

  • 但是,你必须明确地将其添加在"嵌入框架"(尽管这似乎毫无意义,因为它完美的作品时,你只在"嵌入框架"的话),

  • 把它复制框架

  • 确保复制框架 "嵌入框架"之后


Gur*_*ngh 13

感谢以上所有答案。这是一个使用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
Run Code Online (Sandbox Code Playgroud)


Ann*_*awn 11

我会在这里加上我的2美分(以不太可怕的方式:-).我遇到了很多来自供应商的胖库(由于某种原因),通过将它们添加到FrameworksApple记录的目录中而无法正常工作.我们已经能够使他们的工作的唯一方法是通过拉动.framekwork权到项目目录和链接Embedded Frameworks,并Link Binary with Libraries在构建设置手动.这似乎已经没有任何问题不过工作,与他们与外来的仿真架构任何脂肪库i386,并x86_64伴随着arm架构.

检查胖库架构的快速方法是

$ cd 'Project_dir/Project'
$ lipo -info 'YourLibrary.framework/YourLibExec`
Run Code Online (Sandbox Code Playgroud)

哪个应该吐出像这样的输出

Architectures in the fat file: YourLibrary.framework/YourLibExec are: i386 x86_64 armv7 arm64
Run Code Online (Sandbox Code Playgroud)

这证实您需要在iTunesConnect Archival上传之前从您的框架中"削减脂肪"(即i386&x86_64),这不允许这些体系结构(因为它们不支持iOS).

现在,所有答案(或至少一些答案)都提供了这些精彩的运行脚本,我确信它们确实很有效,但前提是您的Framework位于Frameworks目录中.现在,除非你是一个shell脚本垃圾,那些没有修改的脚本将不适用于我上面解释的场景.然而,有摆脱的一个非常简单的方法i386:x86_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.上面的命令只是通过首先重命名可执行文件然后最终删除所需的arch,然后清理左边的文件来完成.就是这样,您现在应该看到Application Loader Archival上传到iTunesConnect的绿色复选标记.

需要记住的事项:上述步骤只应在生产构建时完成,因为.framework将从模拟器架构中剥离,模拟器上的构建将停止工作(这是预期的).在开发环境中,不需要从.framework文件中剥离体系结构,因为您希望能够在模拟器和物理设备上进行测试.如果您的胖库位于Frameworks项目的文件夹中,请查看接受的答案.


MAh*_*ngh 11

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

  • 所有列出的最简单的解决方案。非常感谢! (2认同)

Flo*_*bre 9

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

确保在xCode中,在嵌入之后添加脚本.我想我在嵌入式框架之前不小心移动了脚本.

在此输入图像描述

注意:我有xCode 9.1


Kir*_*hav 7

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

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

请参阅下面的屏幕截图;

在此处输入图片说明


Mih*_*rős 5

我从构建设置 - 有效架构 - 发布中删除了架构 i386 和 x64_86,并且一切正常。

在此处输入图片说明

现在唯一的问题是您不能在SIMULATOR上运行用于测试目的的RELEASE构建。但是,就像您移除拱门一样容易,如果您愿意,也可以将它们重新添加回来。


obj*_*y C 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
Run Code Online (Sandbox Code Playgroud)