J'ai un projet Xcode 10 - iOS12 Swift qui établit des liens avec Mon propre framework (également Xcode 10 + iOS12).
Le projet d'application référence mon projet-cadre en tant que référence de sous-projet.
Le projet My Framework fait référence à PromiseKit.framework (un framework universel - bibliothèque de ressources), créé à l'aide du script de génération suivant:
# 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
Lorsque je vais archiver mon projet d'application parent à l'aide de Xcode 10 (et aussi 9.4.1) avec Bitcode ON (qui contient la référence My Framework et la bibliothèque PromiseKit Fat), l'erreur suivante apparaît à l'étape de signature: (Échec de la vérification du bitcode in PromiseKit.framework/PromiseKit: erreur Impossible d'extraire le paquet de /var/folders..../(x86_64) - ce qui suggère qu'il est lié à la tranche de simulateur)
Si je désactive l'option "Rebuild from Bitcode" de l'organiseur, le message d'erreur suivant s'affiche: (La signature du code "PromiseKit.framework" a échoué)
Cependant, si j'utilise Xcode 9.4.1 avec Bitcode OFF, il exporte et signe correctement.
Pourquoi tente-t-il de signer individuellement de nouveau les sous-cadres et que puis-je faire pour atténuer les problèmes? J'ai besoin que l'archivage fonctionne normalement avec Xcode 10, ainsi que de futures dépendances tierces ajoutées à ma cible d'infrastructure. (Il s'agit de la première dépendance dynamique du cadre ajoutée à ma cible. Avant de commencer à «cuisiner» - intégrer toutes les tierces parties pour faciliter le développement, mais PromiseKit est difficile à intégrer en raison de la dépendance importante vis-à-vis d'Objectif-c).
Le journal d'archive Xcode est:
{
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";
}
);
Certaines autres solutions que j'ai essayées utilisaient une référence de projet à PromiseKit, au lieu d'une référence de cadre, mais cela ne fonctionne pas - dans la mesure où j'ai toujours besoin d'une référence de cadre de mon projet principal, car l'erreur "librairie non chargée" sera générée à runtime, si exécuté sans référence FW. Le même problème se produit lors de l'archivage lors de l'utilisation d'une référence de projet.
Essaye ça! Cela a fonctionné pour moi et beaucoup d'autres personnes:
Aller à
Phases de construction> Ajouter> Nouvelle phase de script d'exécution
Le code devrait fonctionner pour n’importe quel shell par défaut, mais je recommande simplement d’utiliser/bin/sh
et inclure le code suivant:
# 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
Il semble que certains frameworks livrent des architectures, qui ne seront pas utilisées dans l'application . Xcode refusera de les signer. Le script ci-dessus supprime les architectures inutilisées.
Crédits: Un gars de GitHub, je ne trouve plus la source exacte.
Même problème ici. La seule solution que j'ai trouvée consiste à utiliser une bibliothèque statique au lieu de framework.
Si vous ne pouvez pas utiliser la bibliothèque statique, vous feriez mieux de déposer un rapport de bogue auprès d'Apple.
J'ai pu intégrer (compiler dans le cadre de mon cadre) - le code cadre tiers, sans le référencer en tant que cadre. Je devais refactoriser -> renommer quelques-unes des classes qui entraient en conflit avec le nom de mon nom. Je ne voulais pas avoir cette complexité supplémentaire de références inter-infrastructures et de tranches d'architecture manquantes/supplémentaires. Étant donné que je privilégie la simplicité à tout le reste, cette solution a fonctionné au mieux pour moi.