检查并删除IPA /存档

时间:2017-03-07 06:39:06

标签: ios xcode app-store

问题:

在将应用程序提交到App Store时,会报告以下错误:

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

的问题:

  1. 如何解决上述错误?

  2. 如何查看存档或IPA使用的体系结构?

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

    • 是否只能通过脚本或Build Settings或其他地方有设置?

5 个答案:

答案 0 :(得分:67)

Apple已开始抱怨应用程序是否包含分发期间的模拟器架构。

如何解决上述错误?

解决方案:

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

Shell:

/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

输出将是: →胖文件中的体系结构:ProjectName是:     i386 x86_64 armv7 arm64

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

答案 1 :(得分:6)

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

  1. 打开终端

  2. 打开各个框架到终端的项目拖动路径

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

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

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

答案 2 :(得分:4)

对于构建阶段下的运行脚本,将以下步骤添加到运行脚本中以删除 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

答案 3 :(得分:1)

对于iOS项目,您具有以下架构:arm64 armv7 armv7s i386 x86_64

x86_64i386用于模拟器。

可能的问题是您使用的框架是为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”并使用它。

编码愉快!

答案 4 :(得分:0)

使用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