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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Xcode 10:代码签名我的App + Framework失败,因为签署第三方依赖框架(PromiseKit)失败。适用于Xcode 9相关的知识,希望对你有一定的参考价值。

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

应用程序项目将我的框架项目作为子项目引用引用。

My Framework项目引用了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

当我使用Xcode 10(以及9.4.1)使用Bitcode ON(包含My Framework引用和PromiseKit Fat库)来存档我的父App项目时,我在签名阶段出现以下错误:(无法验证bitcode在PromiseKit.framework / PromiseKit:错误无法从/var/folders提取包(/ x86_64) - 这表明它的模拟器切片相关)enter image description here

如果我将管理器中的“从Bitcode重建”选项设置为OFF,那么我会得到一个不同的错误:(代码签名“PromiseKit.framework”失败)enter image description here

但是,如果我使用Xcode 9.4.1 Bitcode OFF,那么它会导出并签名正常。

为什么要尝试单独重新签署子框架,我该怎么做才能缓解问题?我需要使用Xcode 10正常工作,以及将来添加到我的框架目标的任何第三方依赖项。 (这是我的框架目标中添加的第一个动态框架依赖项。在我进行“烘焙”之前 - 为了便于开发而加入所有第三方,但由于对Objective-c的广泛依赖,PromiseKit难以进入。

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:
error: Cannot extract bundle from /var/folders/q5/hm9v_6x53lj0gj02yxqtkmd40000gn/T/IDEDistributionOptionThinning.RJD/Payload/MyAppName.app/Frameworks/PromiseKit.framework/PromiseKit (x86_64)

";
        info =             {
        };
        level = ERROR;
        type = "malformed-payload";
    }
);

我尝试的其他一些解决方案是使用Project Reference to PromiseKit而不是Framework引用,但是这不起作用 - 因为我仍然需要来自我的主项目的框架引用,因为我将得到“库未加载”错误运行时,如果没有FW引用运行。使用项目引用进行归档时会出现相同的问题。

答案

试试这个!它对我和许多其他人有用:

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

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

并包含以下代码:

# 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

似乎有些框架出货架构,不会在应用程序中使用。 Xcode将拒绝签名。以上脚本删除了未使用的体系结构。

致谢:GitHub的一些人,我找不到确切的消息来源了。

另一答案

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

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

另一答案

我能够在板上(作为我的框架的一部分编译) - 第三方框架代码,而不将其作为框架引用。我不得不重构 - >重命名一些与我自己命名冲突的类。我不希望增加框架间引用和缺少/额外架构切片的复杂性。由于我优先考虑简单性,所以这个解决方案最适合我。

以上是关于Xcode 10:代码签名我的App + Framework失败,因为签署第三方依赖框架(PromiseKit)失败。适用于Xcode 9的主要内容,如果未能解决你的问题,请参考以下文章

10.9.5 下的 Xcode 6.0.1 会自动使用新的“版本 2 签名”对我的应用程序进行签名吗?

XCode 代码签名错误 XCTest

Xcode 10:代码签名身份中的不代码签名选项在哪里

Xcode 10 签名错误:Frameworks/libswiftsimd.dylib:代码对象根本没有签名

Xcode-5 验证错误。无效的代码签名权利

iPad App 的临时分发的代码签名问题