【问题标题】:Check and Remove Unsupported Architecture [x86_64, i386] in IPA / Archive检查并删除 IPA / 存档中不受支持的架构 [x86_64, i386]
【发布时间】:2017-07-27 06:40:18
【问题描述】:

问题:

将应用提交到 App Store 时报告以下错误:

Unsupported Architecture. Your executable contains unsupported architecture '[x86_64, i386]

问题:

  1. 上述错误如何解决?

  2. 如何检查存档或 IPA 使用的架构?

  3. 如何确保Release 存档不包含x86_64i386(模拟器架构)。

    • 是否只能通过脚本实现,或者Build Settings 中有设置还是在哪里?

【问题讨论】:

  • 进入构建设置-> 搜索“架构”,你可以在里面查看“架构”选项卡,一般默认必须是armv7,arm64架构,请查看显示给你的是哪一个
  • 另外,有时会出现上述错误,因为构建不当,请清理,然后构建,然后归档并上传(不要忘记清理然后构建)。让我们再试一次.. 可能你会以这种方式获得成功
  • 我想问题是使用的一些框架是构建的,包括 x86_64 和 i386 架构。所以必须手动删除它。

标签: ios xcode app-store


【解决方案1】:

如果应用在分发过程中包含模拟器架构,Apple 已开始抱怨。

如何解决上述错误?

解决方案:

在项目目标的运行脚本中添加以下代码,这会在构建过程中从您的应用程序中删除模拟器架构(x86_64 和 i386):

壳牌:

/bin/sh

代码:

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

解决方案:

还有另一种解决方案,如果您只想执行一次。 但请注意,尽管执行以下步骤后,您将无法在模拟器上运行应用程序。在将应用部署到 Testflight/App-store 之前执行此操作。

从终端进入项目的 ProjectFramework.framework 文件夹。运行以下命令:

lipo -remove i386 ProjectFramework_SDK -o ProjectFramework_SDK 
lipo -remove x86_64 ProjectFramework_SDK -o ProjectFramework_SDK

检查框架中的架构?

$ lipo -info PathToProject/ProjectName.framework/ProjectName

输出将是: → fat 文件中的架构: ProjectName 是: i386 x86_64 armv7 arm64

参考。文档: http://ikennd.ac/blog/2015/02/stripping-unwanted-architectures-from-dynamic-libraries-in-xcode/

【讨论】:

  • 谢谢,注意到stackoverflow.com/questions/30547283/submit-to-app-store-issues中的相同解决方案
  • 是的,您肯定可以完全回答。如果代码是从不同的地方引用的,最好提供引用的链接,以便他们得到认可。
  • 如何从 IPA 而不是框架中找到架构?此外,如果代码是从其他地方/stackoverflow 答案引用的,请提供原始链接而不是代码
  • 我从我提到的博客站点中引用,另一个解决方案的一部分是由我实现的,就是这样。
  • 运行脚本必须放在嵌入框架的步骤之后
【解决方案2】:

用于自定义创建的动态框架

  1. 打开终端

  2. 打开你的项目拖拽路径到终端

    例如cd /Users/mahipal/Desktop/masterTest/Alamofire.framework

  3. 在下面的命令中设置你的框架名称并运行

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

【讨论】:

  • 嗨,我删除了 x86_64:" lipo -remove x86_64 WebRTC -o WebRTC" ---> 但现在我的 .项目出现 21 错误 :(,不知道为什么,你能帮忙,我正在使用模拟器
  • 示例:“显示所有消息忽略文件 /Users/thehe/Documents/Work/XXX/WebRTC.framework/WebRTC,在文件 /Users/thehe/Documents/Work/XXXX/ 中缺少所需的架构 x86_64 WebRTC.framework/WebRTC(2 片)“-----”显示所有消息未定义符号:_RTCInitializeSSL“
  • @famfamfam ,实际上模拟器只支持 x86_64 架构框架。所以你需要编译和生成模拟器的框架也支持但是当你尝试在商店上传二进制文件然后删除那个 x86_64 框架
  • tks 你,所以现在我有 2 个框架:1 个用于模拟器,1 个用于提交:D
【解决方案3】:

对于构建阶段下的运行脚本,将以下步骤添加到运行脚本以删除x86_64和/或i386强>:

cd "${ARTIFACTS_FOLDER}"/FrameworkName.framework

lipo -remove x86_64 FrameworkName -o FrameworkName
lipo -remove i386 FrameworkName -o FrameworkName

可以组合删除多个架构:

lipo -remove x86_64 FrameworkName -o FrameworkName && lipo -remove i386 FrameworkName -o FrameworkName

【讨论】:

    【解决方案4】:

    当使用 nikdange_me 的脚本时,我得到了:

    error: exportArchive: ipatool failed with an exception: #<CmdSpec::NonZeroExcitException: ... >
    error: Framework not found in dylib search path
    

    所以我改变了它并使用lipo -remove 而不是lipo -extractlipo -create 这解决了我的问题:

    # This script loops through the frameworks embedded in the application 
    # and removes unused architectures.
    
    find "${TARGET_BUILD_DIR}/${WRAPPER_NAME}" -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"
        for arch in $(lipo -archs $FRAMEWORK_EXECUTABLE_PATH); do
            if ! printf '%s\n' ${ARCHS[@]} | egrep -q "^$arch$"; then
                lipo -remove $arch "$FRAMEWORK_EXECUTABLE_PATH" -o "$FRAMEWORK_EXECUTABLE_PATH" 
            fi
        done
    done
    

    【讨论】:

      【解决方案5】:

      对于一个 iOS 项目,你有以下架构:arm64armv7armv7si386x86_64

      x86_64, i386 用于模拟器。

      您的问题可能是您使用的框架是为 iOS 构建的,而不是模拟器。

      要解决此问题,您可以绕过构建框架并使用 lipo 命令行。

      第一lipo -info [The library.framework location]

      使用示例lipo -info /Users/.../library.framework/LibrarySDK

      示例输出

      Architectures in the fat file: /Users/.../library.framework/LibrarySDK are: i386 x86_64 armv7 arm64 
      

      您将获得用于该框架的架构列表。

      第二个:我们需要从模拟器架构中剥离框架,并制作该框架的 2 个版本(1 个用于 iOS 设备,1 个用于模拟器)

      使用lipo -remove [architecture] [location] -o [output_location]

      示例lipo -remove i386 /Users/.../SDK -o /Users/.../SDK_Output_Directory

      转到您选择的输出目录以获取新生成的 SDK,而无需删除架构,以验证您是否可以使用与上述相同的 lipo -info 命令

      您可以在新创建的 SDK 上使用相同的 lipo remove 命令,但使用其他架构 lipo -remove x86_64 ...,您将获得仅适用于 iOS 设备的 SDK

      第三:获取最终的 SDK 并将其重命名为“SDK_Name_IOS”并使用它。

      编码愉快!!

      【讨论】:

        猜你喜欢
        • 2014-11-11
        • 2013-01-17
        • 2014-12-02
        • 2017-07-11
        • 2018-02-26
        • 1970-01-01
        • 2013-12-10
        • 1970-01-01
        • 2015-03-22
        相关资源
        最近更新 更多