Kit Média macOS Correctif du Crash de Codesign
Problème
Les applications Flutter macOS utilisant media_kit (bibliothèque de lecteur vidéo) plantent immédiatement au lancement après une génération complète. L'app se génère avec succès mais échoue au démarrage en raison de frameworks natifs non signés.
Contexte / Conditions de déclenchement
- Application Flutter macOS utilisant le package
media_kitoumedia_kit_video - L'app se génère sans erreurs : « Built build/macos/Build/Products/Debug/divine.app »
- L'app plante immédiatement au lancement sans interface visible
- Le rapport de crash ou la console affiche :
Library not loaded: @rpath/Ass.framework/Versions/A/Ass Reason: code signature in '...' not valid for use in process: Trying to load an unsigned library - Se produit souvent après
flutter clean,pod deintegrate+pod install, ou après un clone git frais - CRITIQUE : Peut aussi se produire quand le script de codesign existe MAIS s'exécute dans le mauvais ordre
Cause racine : Ordre des phases de compilation
La cause la plus courante (surtout après pod deintegrate + pod install) est que les phases de compilation Xcode se retrouvent dans le mauvais ordre :
MAUVAIS ordre (codesign s'exécute avant que les frameworks soient copiés) :
1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. Codesign media_kit frameworks ← NE SIGNE RIEN (frameworks pas encore embarqués)
8. [CP] Embed Pods Frameworks ← copie les frameworks dans le bundle de l'app
BON ordre (embarquer d'abord, puis codesigner) :
1. [CP] Check Pods Manifest.lock
2. Sources
3. Frameworks
4. Resources
5. Bundle Framework
6. ShellScript (Flutter assemble)
7. [CP] Embed Pods Frameworks ← copie les frameworks dans le bundle de l'app
8. Codesign media_kit frameworks ← signe les frameworks embarqués
9. FlutterFire upload symbols ← (si applicable, devrait être en dernier)
Solution
Étape 1 : Ajouter la phase de codesign via Podfile (si manquante)
Ajoutez ce bloc dans la section post_install do |installer| :
post_install do |installer|
# Add script phase to codesign media_kit frameworks (fixes unsigned library crash)
installer.pods_project.targets.each do |target|
if target.name == 'media_kit_libs_macos_video'
target.build_configurations.each do |config|
config.build_settings['CODE_SIGN_IDENTITY'] = '-'
end
end
end
# Also add codesigning to the main project's frameworks
main_project = installer.aggregate_targets.first.user_project
main_project.targets.each do |target|
if target.name == 'Runner'
# Check if script phase already exists
phase_name = 'Codesign media_kit frameworks'
existing_phase = target.shell_script_build_phases.find { |p| p.name == phase_name }
unless existing_phase
phase = target.new_shell_script_build_phase(phase_name)
phase.shell_script = <<-SCRIPT
# Codesign media_kit frameworks with ad-hoc signature
for framework in "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/Contents/Frameworks"/*.framework; do
if [ -d "$framework" ]; then
codesign --force --deep --sign - "$framework" 2>/dev/null || true
fi
done
SCRIPT
phase.shell_path = '/bin/bash'
end
end
end
main_project.save
# ... rest of your existing post_install code ...
Étape 2 : Vérifier l'ordre des phases de compilation (CRITIQUE)
Le Podfile ajoute la phase de codesign mais ne peut pas garantir l'ordre. Après pod install, vérifiez macos/Runner.xcodeproj/project.pbxproj pour le tableau buildPhases de la cible Runner.
Recherchez le bloc buildPhases dans la section de la cible native Runner. Assurez-vous de cet ordre :
[CP] Embed Pods Frameworks ← DOIT être AVANT codesign
Codesign media_kit frameworks ← DOIT être APRÈS embed
FlutterFire: upload symbols ← DEVRAIT être en dernier (si présent)
Si l'ordre est mauvais, inversez les lignes du tableau buildPhases. Exemple de correction :
buildPhases = (
...
3399D490228B24CF009A79C7 /* ShellScript */,
- 9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
- 51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
- BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
+ 51BD49356784271F7E3B2B6C /* [CP] Embed Pods Frameworks */,
+ 9AD7FD721DF2C6A84F6A1FC3 /* Codesign media_kit frameworks */,
+ BBC532B406767D40236ED3DB /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
);
Étape 3 : Regénérer
flutter clean
flutter pub get
cd macos && pod install && cd ..
flutter run -d macos
Correctif rapide d'urgence (Codesign manuel)
Si vous avez besoin que l'app fonctionne MAINTENANT avant de corriger les phases de compilation :
for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
codesign --force --deep --sign - "$fw"
done
codesign --force --deep --sign - "build/macos/Build/Products/Debug/<app>.app"
open "build/macos/Build/Products/Debug/<app>.app"
Vérification
- La sortie de compilation devrait afficher : « warning: Run script build phase 'Codesign media_kit frameworks' will be run during every build »
- L'app devrait se lancer sans plantage
- Vérifiez que les frameworks sont signés :
codesign -v build/macos/.../app.app/Contents/Frameworks/Ass.framework
Diagnostic des problèmes d'ordre des phases de compilation
Si le script de codesign existe mais les frameworks sont toujours non signés, vérifiez l'ordre :
# Check which frameworks are unsigned in the built app
for fw in build/macos/Build/Products/Debug/<app>.app/Contents/Frameworks/*.framework; do
result=$(codesign -v "$fw" 2>&1)
if echo "$result" | grep -q "not signed"; then
echo "UNSIGNED: $(basename $fw)"
fi
done
Si TOUS les frameworks media_kit (Ass, Avcodec, Avformat, etc.) sont non signés mais que le script de codesign existe dans le projet, c'est presque certainement un problème d'ordre des phases de compilation.
Notes
- Ceci affecte principalement les générations de débogage ; les générations de production avec signature de code appropriée peuvent ne pas avoir besoin de ceci
- L'identité de signature
-signifie une signature ad-hoc (aucun certificat requis) - Les frameworks affectés de media_kit incluent :
Ass.framework,Avcodec.framework,Avformat.framework,Avutil.framework,Dav1d.framework,Freetype.framework,Fribidi.framework,Harfbuzz.framework,Mbedcrypto.framework,Mbedtls.framework,Mbedx509.framework,Mpv.framework,Png16.framework,Swresample.framework,Swscale.framework,Uchardet.framework,Xml2.framework - Le
|| truedans le script empêche les échecs de compilation si la signature échoue pour un framework - L'ordre des phases de compilation peut s'arrêter silencieusement après des cycles
pod deintegrate+pod install - L'API CocoaPods
new_shell_script_build_phaseajoute à la fin des phases de compilation, ce qui peut être APRÈS la propre phase d'embarquement de CocoaPods—mais après la réinstallation de pods, la phase d'embarquement peut être rajoutée à la très fin, la poussant APRÈS votre phase de codesign
Lié : Avertissement Mpv.framework en double
Si vous voyez des avertissements du runtime ObjC comme :
Class Application is implemented in both .../Mpv.framework/Versions/A/Mpv (0xADDR1) and
.../Mpv.framework/Versions/A/Mpv (0xADDR2). This may cause spurious casting failures.
Cela indique que Mpv.framework est chargé deux fois, souvent causé par l'utilisation d'un fork git de media_kit_video aux côtés du media_kit_libs_macos_video de pub.dev. Le podspec du fork lie -framework Mpv directement tandis que le package libs le vend aussi. Cela peut causer une corruption du cache de config mpv et des plantages comme :
Assertion failed: (group_index >= 0), function m_config_cache_from_shadow, file m_config_core.c
Une génération complète résout généralement ceci. Si persiste, envisagez de basculer vers la version publiée de media_kit_video.
Références
- media_kit GitHub : https://github.com/media-kit/media-kit
- Apple Code Signing Guide : https://developer.apple.com/documentation/security/code_signing_services