web-dev-qa-db-ja.com

Xcode 10:サードパーティの依存関係フレームワーク(PromiseKit)の署名に失敗したため、App + Frameworkのコード署名が失敗します。 Xcode 9で動作します

Xcode 10-iOS12 Swift自分のフレームワーク(Xcode 10 + iOS12)にリンクするプロジェクト)があります。

アプリプロジェクトは、私のフレームワークプロジェクトをサブプロジェクト参照として参照しています。

私のフレームワークプロジェクトは、次のビルドスクリプトを使用して作成されたPromiseKit.framework(ユニバーサルフレームワーク-fatライブラリ)を参照します。

# 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ライブラリを含む)を使用して親アプリプロジェクトをアーカイブすると、署名段階で次のエラーが発生します:(ビットコードの検証に失敗しましたPromiseKit.framework/PromiseKitのエラー:/var/folders..../(x86_64)からバンドルを抽出できません-これはシミュレータスライスに関連していることを示唆しています) enter image description here

オーガナイザーの[ビットコードから再構築]オプションをオフにすると、別のエラーが表示されます:(コード署名 "PromiseKit.framework"が失敗しました) enter image description here

ただし、ビットコードがオフの状態でXcode 9.4.1を使用すると、エクスポートして正常に署名されます。

サブフレームワークに個別に再署名しようとするのはなぜですか、問題を軽減するために何ができますか?フレームワークターゲットに追加される将来のサードパーティの依存関係とともに、Xcode 10で正常に動作するためにアーカイブが必要です。 (これは、Frameworkターゲットに追加された最初の動的フレームワーク依存関係です。「焼き付ける」前-開発を容易にするためにすべてのサードパーティをインボーディングしましたが、PromiseKitはObjective-cへの広範な依存関係によりインボードが困難です)。

Xcode Archiveログは次のとおりです。

 {
        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";
    }
);

私が試した他のいくつかのソリューションは、フレームワーク参照の代わりにPromiseKitへのプロジェクト参照を使用していましたが、これは動作しません-メインプロジェクトからのフレームワーク参照が必要です。 FW参照なしで実行している場合、ランタイム。プロジェクト参照の使用中にアーカイブすると、同じ問題が発生します。

11
FranticRock

これを試して!それは私と他の多くの人々のために働いた:

後藤

ビルドフェーズ>追加>新しいスクリプト実行フェーズ

コードはどのデフォルトシェルでも機能するはずですが、/ 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のある人、正確なソースはもう見つかりません。

24
YoshiJaeger

ここで同じ問題。私が見つけた唯一の回避策は、フレームワークの代わりに静的ライブラリを使用することです。

静的ライブラリを使用できない場合は、アップルにバグレポートを提出することをお勧めします。

2
Dion Cho

フレームワークとして参照せずに、サードパーティのフレームワークコードをインボード(フレームワークの一部としてコンパイル)できました。私はリファクタリングする必要がありました->命名で競合するいくつかのクラスの名前を自分のものに変更しました。私は、フレームワーク間の参照の複雑さを追加したり、アーキテクチャスライスが欠落/追加されたりすることを望みませんでした。私は他のすべてよりも単純さを優先しているので、このソリューションは私にとって最もうまくいきました。

1
FranticRock