wake-up-neo.com

Xcode 10: Code Das Signieren meines App + Framework schlägt fehl, da das Drittanbieter-Abhängigkeits-Framework (PromiseKit) nicht signiert werden kann. Funktioniert in Xcode 9

Ich habe ein Xcode 10 - iOS12 Swift-Projekt, das mit meinem eigenen Framework (auch Xcode 10 + iOS12) verknüpft ist. 

Das App-Projekt referenziert mein Rahmenprojekt als Referenz für ein Unterprojekt.

Mein Framework-Projekt verweist auf PromiseKit.framework (eine universelle Framework-Fat-Bibliothek), die mit dem folgenden Build-Skript erstellt wurde: 

# 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

Wenn ich mein übergeordnetes App-Projekt mit Xcode 10 (und auch 9.4.1) mit Bitcode ON (das die Referenz für meinen Framework und die PromiseKit-Fat-Bibliothek enthält) archiviert, erhalte ich in der Signierphase die folgende Fehlermeldung: (Fehler beim Überprüfen des Bitcodes.) in PromiseKit.framework/PromiseKit: error Das Paket kann nicht aus /var/folders..../(x86_64) extrahiert werden. Dies legt nahe, dass es sich um einen Simulator-Slice handelt.)  enter image description here

Wenn ich im Organizer die Option "Rebuild from Bitcode" auf "OFF" schalte, erhalte ich einen anderen Fehler: (Die Signatur des Codes "PromiseKit.framework" ist fehlgeschlagen)  enter image description here

Wenn ich jedoch Xcode 9.4.1 mit "Bitcode OFF" verwende, kann es problemlos exportiert und signiert werden. 

Warum wird versucht, Sub-Frameworks einzeln neu zu signieren, und was kann ich tun, um die Probleme zu lösen? Ich brauche die Archivierung, um normal mit Xcode 10 zu arbeiten, zusammen mit zukünftigen Abhängigkeiten von Drittanbietern, die meinem Framework-Ziel hinzugefügt werden. (Dies ist die erste dynamische Framework-Abhängigkeit, die zu meinem Framework-Ziel hinzugefügt wurde. Bevor ich "gebacken" wurde - das Einbinden aller Drittanbieter zur Vereinfachung von Entwicklungszwecken, PromiseKit ist jedoch aufgrund der umfangreichen Abhängigkeiten von Objective-c) schwer zu integrieren. 

Das Xcode-Archivprotokoll lautet:

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

Einige andere Lösungen, die ich ausprobiert habe, waren die Verwendung einer Projektreferenz auf PromiseKit anstelle einer Frameworkreferenz. Dies funktioniert jedoch nicht - da ich immer noch eine Frameworkreferenz aus meinem Hauptprojekt benötige, weil ich die Fehlermeldung "Bibliothek nicht geladen" bekomme Laufzeit, wenn ohne FW-Referenz ausgeführt wird. Das gleiche Problem tritt bei der Archivierung bei Verwendung einer Projektreferenz auf. 

5
FranticRock

Versuche dies! Es hat für mich und viele andere Leute funktioniert:

Gehe zu

Phasen erstellen> Hinzufügen> Neue Skriptphase

Der Code sollte für jede Standard-Shell funktionieren, aber ich empfehle, nur/bin/sh zu verwenden.

und füge folgenden Code hinzu:

# 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

Es scheint, als hätten einige Frameworks Schiffsarchitekturen, die nicht in der Anwendung verwendet werden. Das obige Skript entfernt nicht verwendete Architekturen.

Credits: Ein Typ bei GitHub, ich kann die genaue Quelle nicht mehr finden.

4
SmartArray

Gleiche Ausgabe hier. Die einzige Problemumgehung, die ich gefunden habe, ist die Verwendung einer statischen Bibliothek anstelle eines Frameworks. 

Falls Sie keine statische Bibliothek verwenden können, sollten Sie einen Fehlerbericht an Apple senden. 

2
Dion Cho

Ich konnte den Drittanbieter-Framework-Code integrieren (als Teil meines Frameworks kompilieren), ohne ihn als Framework zu bezeichnen. Ich musste umgestalten -> einige Klassen umbenennen, die bei der Benennung mit meinen eigenen in Konflikt standen. Ich wollte nicht diese zusätzliche Komplexität von Verweisen auf das Framework und fehlende/zusätzliche Architektur-Slices haben. Da ich der Einfachheit Vorrang vor allem anderen einräumte, hat diese Lösung für mich am besten funktioniert. 

0
FranticRock