Xcode 10:代码签名我的 App+Framework 失败,因为签名 3rd 方依赖框架 (PromiseKit) 失败。适用于 Xcode 9

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/53050451/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 10:51:32  来源:igfitidea点击:

Xcode 10: Code Signing my App+Framework fails, because of failure signing 3rd party dependency framework (PromiseKit). Works in Xcode 9

swiftxcodeframeworkscode-signingxcode10

提问by FranticRock

I have an Xcode 10 - iOS12 swift project that links against My own framework (also Xcode 10 + iOS12).

我有一个 Xcode 10 - iOS12 swift 项目,它链接到我自己的框架(还有 Xcode 10 + iOS12)。

The app project is referencing my framework project as a sub-project reference.

app 项目将我的框架项目作为子项目参考。

My Framework project references PromiseKit.framework (a universal framework - fat library), made using the following build script:

我的框架项目引用了 PromiseKit.framework(一个通用框架 - 胖库),使用以下构建脚本制作:

# Merge Script

# 1
# Set bash script to exit immediately if any commands fail.
set -e

# 2
# Setup some constants for use later on.
FRAMEWORK_NAME="PromiseKit"

# 3
# If remnants from a previous build exist, delete them.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

# 4
# Build the framework for device and for simulator (using
# all needed architectures).
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch arm64 only_active_arch=no defines_module=yes -sdk "iphoneos"
xcodebuild -target "${FRAMEWORK_NAME}" -configuration Release -arch x86_64 only_active_arch=no defines_module=yes -sdk "iphonesimulator"

# 5
# Remove .framework file if exists on Desktop from previous run.
if [ -d "${SRCROOT}/${FRAMEWORK_NAME}.framework" ]; then
rm -rf "${SRCROOT}/${FRAMEWORK_NAME}.framework"
fi

# 6
# Copy the device version of framework to Desktop.
cp -r "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework" "${SRCROOT}/${FRAMEWORK_NAME}.framework"

# 7
# Replace the framework executable within the framework with
# a new version created by merging the device and simulator
# frameworks' executables with lipo.
lipo -create -output "${SRCROOT}/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphoneos/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}" "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/${FRAMEWORK_NAME}"

# 8
# Copy the Swift module mappings for the simulator into the
# framework.  The device mappings already exist from step 6.
cp -r "${SRCROOT}/build/Release-iphonesimulator/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule/" "${SRCROOT}/${FRAMEWORK_NAME}.framework/Modules/${FRAMEWORK_NAME}.swiftmodule"

# 9
# Delete the most recent build.
if [ -d "${SRCROOT}/build" ]; then
rm -rf "${SRCROOT}/build"
fi

When I go to archive my Parent App Project using Xcode 10 (And also 9.4.1) with Bitcode ON (that contains My Framework reference, and PromiseKit Fat library), I get the following error on the Signing stage: (Failed to verify bitcode in PromiseKit.framework/PromiseKit: error Cannot extract bundle from /var/folders..../(x86_64) - which suggests that it's simulator slice related) enter image description here

当我使用 Xcode 10(以及 9.4.1)和 Bitcode ON(包含我的框架参考和 PromiseKit Fat 库)归档我的父应用程序项目时,我在签名阶段收到以下错误:(无法验证位码在 PromiseKit.framework/PromiseKit 中:错误无法从 /var/folders..../(x86_64) 中提取包 - 这表明它与模拟器切片相关) 在此处输入图片说明

If I turn the "Rebuild from Bitcode" option in the Organizer to OFF, then I get a different error: (Code signing "PromiseKit.framework" failed) enter image description here

如果我将 Organizer 中的“Rebuild from Bitcode”选项设置为 OFF,则会出现不同的错误:(代码签名“PromiseKit.framework”失败) 在此处输入图片说明

However, if I use Xcode 9.4.1 With Bitcode OFF, then it exports and signs fine.

但是,如果我在 Bitcode 关闭的情况下使用 Xcode 9.4.1,那么它会导出并正常签名。

Why is it trying to individually re-sign sub frameworks, and what can I do to alleviate the issues? I need the archiving to work normally with Xcode 10, along with any future third party dependencies being added to my framework target. (This is the first dynamic framework dependency added to my Framework target. Before I was "baking in" - in-boarding all 3rd parties for ease of development purposes, but PromiseKit is difficult to inboard due to extensive dependencies on Objective-c).

为什么要尝试单独重新签署子框架,我可以做些什么来缓解这些问题?我需要存档才能与 Xcode 10 一起正常工作,以及将任何未来的第三方依赖项添加到我的框架目标中。(这是第一个添加到我的 Framework 目标中的动态框架依赖项。在我“烘焙”之前 - 将所有 3rd 方引入以简化开发目的,但由于对 Objective-c 的广泛依赖,PromiseKit 很难引入)。

The Xcode Archive log is:

Xcode 存档日志是:

 {
        code = 330;
        description = "Failed to resolve linkage dependency PromiseKit x86_64 -> @rpath/libswiftFoundation.dylib: Unknown arch x86_64";
        info =             {
        };
        level = WARN;
    },
            {
        code = 330;
        description = "Failed to resolve linkage dependency PromiseKit x86_64 -> @rpath/libswiftObjectiveC.dylib: Unknown arch x86_64";
        info =             {
        };
        level = WARN;
    },
            {
        code = 0;
        description = "Failed to verify bitcode in PromiseKit.framework/PromiseKit:\nerror: Cannot extract bundle from /var/folders/q5/hm9v_6x53lj0gj02yxqtkmd40000gn/T/IDEDistributionOptionThinning.RJD/Payload/MyAppName.app/Frameworks/PromiseKit.framework/PromiseKit (x86_64)\n\n";
        info =             {
        };
        level = ERROR;
        type = "malformed-payload";
    }
);

Some other solutions I tried was using a Project Reference to PromiseKit, instead of a Framework reference, however this doesn't work - in that I still need a framework reference from my main project, because I will get "library not loaded" error at runtime, if running without a FW reference. Same issue occurs when archiving while using a project reference.

我尝试过的其他一些解决方案是使用对 PromiseKit 的项目引用,而不是框架引用,但是这不起作用 - 因为我仍然需要来自我的主项目的框架引用,因为我会收到“库未加载”错误运行时,如果在没有 FW 引用的情况下运行。使用项目参考进行归档时会出现同样的问题。

回答by YoshiJaeger

Try this! It worked for me and many other people:

尝试这个!它对我和其他许多人都有效:

Goto

Build phases > Add > New Run Script Phase

构建阶段 > 添加 > 新建运行脚本阶段

The code should work for any default shell, but I recommend just using /bin/sh

该代码应该适用于任何默认 shell,但我建议只使用/bin/sh

and include the following code:

并包含以下代码:

# Type a script or drag a script file from your workspace to insert its path.
# skip if we run in debug
if [ "$CONFIGURATION" == "Debug" ]; then
echo "Skip frameworks cleaning in debug version"
exit 0
fi

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

It seems hat some frameworks ship architectures, that will not be used in the application. Xcode will refuse to sign them. The above script removes unused architectures.

似乎某些框架提供了不会在应用程序中使用的架构。Xcode 将拒绝签署它们。上面的脚本删除了未使用的架构。

Credits: Some guy at GitHub, I can't find the exact source anymore.

致谢:GitHub 上的某个人,我再也找不到确切的来源了。

回答by Dion Cho

Same issue here. The only workaround I've found is to use static library instead of framework.

同样的问题在这里。我发现的唯一解决方法是使用静态库而不是框架。

In case you are not able to use static library, you'd better file a bug report to Apple.

如果您无法使用静态库,您最好向 Apple 提交错误报告。

回答by FranticRock

I was able to in-board (compile as part of my framework) - the third party framework code, without referencing it as a Framework. I had to refactor --> rename a few of the classes which conflicted in naming with my own. I didn't want to have this added complexity of inter-framework references and missing / extra architecture slices. Since I am prioritizing simplicity over everything else, this solution worked for me best.

我能够内置(编译为我的框架的一部分)-第三方框架代码,而无需将其作为框架引用。我不得不重构 --> 重命名一些与我自己的命名冲突的类。我不想增加框架间引用的复杂性和缺失/额外的架构切片。由于我将简单性放在首位,因此此解决方案最适合我。

回答by Freed Ahmad

This is what worked for me, I have application and 2 in-house built frameworks, say A $ B.

这对我有用,我有应用程序和 2 个内部构建的框架,比如A $ B。

Application needs A, but A needs B and since Apple doesn't recommend nesting frameworks, so both A and B had to be included in the app.

应用程序需要 A,但 A 需要 B,而且由于 Apple 不推荐嵌套框架,因此 A 和 B 都必须包含在应用程序中。

This is what my Xcode project looks like.

这就是我的 Xcode 项目的样子。

structure of the application in Xcode

Xcode 中的应用程序结构

SOLUTION

解决方案

In the application, under Frameworks, Libraries and Embedded Content, select Embed & Signfor all necessary frameworks. (as shown below)

在应用程序中,在Frameworks、Libraries 和 Embedded Content 下,为所有必要的框架选择Embed & Sign。(如下所示)

application frameworks

应用框架

But for all the custom framework projects, under Frameworks and Librariessection, select Do Not Embed. (as shown below) This fixed the issue for me

但是对于所有自定义框架项目,在Frameworks and Libraries部分下,选择Do Not Embed。(如下所示)这为我解决了问题

custom frameworks

自定义框架