Xcode 27.2: `copy_bundle.sh` makes simulator installs fail with `DuplicateIdentifier` (`_Testing_CoreTransferable`), and the 2.0.2 fix has a ksh syntax error
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 78/100
Línea de trabajo
Empieza leyendo copy_bundle.sh, especialmente el bucle de copia de frameworks y la condición añadida en 2.0.2; la incidencia identifica al intérprete ksh del sistema como origen del error de sintaxis. Comprueba el manejo de los identificadores de bundle con los frameworks duplicados _Testing_CoreTransferable y _Testing_CoreGraphics; después, ejecuta ksh -n copy_bundle.sh. El objetivo es que el script se analice correctamente y evite copiar frameworks con un identificador de bundle duplicado, manteniendo las demás copias necesarias.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
Summary
On Xcode 27.2, any app that runs copy_bundle.sh in a build phase can't be installed on the simulator any more. The script copies every _Testing_*.framework from the platform's developer Frameworks folder into the app. In Xcode 27.2, _Testing_CoreTransferable.framework has the same CFBundleIdentifier as _Testing_CoreGraphics.framework, so installd rejects the app with MIInstallerErrorDomain code 57 (DuplicateIdentifier).
2.0.2 tries to skip the Transferable framework, but the new condition doesn't parse in ksh. That's the script's interpreter (#!/bin/ksh -x), so the whole script now fails with a syntax error.
Environment
| InjectionNext | 2.0.1 (the bug); 2.0.2, build 14919 (the syntax error) |
| Xcode | 27.2 (27B52) |
| Simulator runtime | iOS 27.2 (24B8117), iPhone19,2 |
| macOS | 27.2.1 (26B131) |
| ksh | sh (AT&T Research) 93u+ 2012-08-01 (the system /bin/ksh) |
Root cause
Xcode 27.2 ships _Testing_CoreTransferable.framework with the wrong bundle identifier. The framework's code signature is valid, so this is how Apple ships it:
$ F=/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks
$ /usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$F/_Testing_CoreGraphics.framework/Info.plist"
com.apple.dt.swift-testing.overlay.CoreGraphics
$ /usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$F/_Testing_CoreTransferable.framework/Info.plist"
com.apple.dt.swift-testing.overlay.CoreGraphics <-- should be ...overlay.CoreTransferable
$ codesign --verify --strict -v "$F/_Testing_CoreTransferable.framework"
... valid on disk
... satisfies its Designated Requirement
(The Info.plist of _Testing_CoreTransferable.framework reports DTXcodeBuild = 27B49.)
Xcode normally puts these overlays only into test bundles, so plain app builds never hit this. copy_bundle.sh copies them into the app's Frameworks folder:
(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
"$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" ]; then
rsync -a "$fwork" "$CODESIGNING_FOLDER_PATH/Frameworks" && codesign ...
With both frameworks in MyApp.app/Frameworks, the simulator install fails in -[MIInstallableBundle performPreflightWithError:].
The 2.0.2 change doesn't parse
2.0.2 changes the condition to:
if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" -a ! ( "$fwork" =~ Transferable ) ]; then
[ (test) supports neither =~ nor unescaped (, so ksh rejects the script before it runs:
$ ksh -n /Applications/InjectionNext.app/Contents/Resources/copy_bundle.sh
/Applications/InjectionNext.app/Contents/Resources/copy_bundle.sh: syntax error at line 63: `(' unexpected
$ echo $?
3
So with 2.0.2 the copy phase fails outright: nothing is copied, including iOSInjection.bundle, and the run-script phase exits non-zero.
Steps to reproduce
- Install Xcode 27.2 (27B52) and InjectionNext 2.0.1.
- Add the usual run-script phase to an iOS app target:
export RESOURCES="/Applications/InjectionNext.app/Contents/Resources" if [ -f "$RESOURCES/copy_bundle.sh" ]; then "$RESOURCES/copy_bundle.sh" fi - Build and run the Debug configuration on an iOS 27.2 simulator.
- 2.0.1: the build succeeds, but the install fails with the error below. 2.0.2: the run-script phase fails with the ksh syntax error.
Expected
The app installs and runs, with the testing frameworks InjectionNext needs copied in, and the script skips (or de-duplicates) the framework whose bundle ID clashes.
Actual (2.0.1), redacted
App installation failed: Unable to Install "MyApp"
Domain: IXUserPresentableErrorDomain
Code: 1
Failure Reason: Please try again later.
Recovery Suggestion: Found bundle at /Users/<user>/Library/Developer/CoreSimulator/Devices/<SIMULATOR-UDID>/data/Library/Caches/com.apple.mobile.installd.staging/temp.<id>/extracted/MyApp.app/Frameworks/_Testing_CoreGraphics.framework with the same identifier (com.apple.dt.swift-testing.overlay.CoreGraphics) as bundle at /Users/<user>/Library/Developer/CoreSimulator/Devices/<SIMULATOR-UDID>/data/Library/Caches/com.apple.mobile.installd.staging/temp.<id>/extracted/MyApp.app/Frameworks/_Testing_CoreTransferable.framework
User Info: {
IDERunOperationFailingWorker = IDELaunchiPhoneSimulatorLauncher;
SimCallingSelector = "installApplication:withOptions:installationInfo:error:";
}
--
Found bundle at .../MyApp.app/Frameworks/_Testing_CoreGraphics.framework with the same identifier (com.apple.dt.swift-testing.overlay.CoreGraphics) as bundle at .../MyApp.app/Frameworks/_Testing_CoreTransferable.framework
Domain: MIInstallerErrorDomain
Code: 57
User Info: {
FunctionName = "-[MIInstallableBundle performPreflightWithError:]";
LegacyErrorString = DuplicateIdentifier;
SourceFileLine = 628;
}
--
Event Metadata: com.apple.dt.IDERunOperationWorkerFinished : {
"device_model" = "iPhone19,2";
"device_osBuild" = "27.2 (24B8117)";
"device_platform" = "com.apple.platform.iphonesimulator";
"launchSession_schemeCommand" = Run;
"launchSession_targetArch" = arm64;
"operation_errorCode" = 1;
"operation_errorDomain" = IXUserPresentableErrorDomain;
"operation_errorWorker" = IDELaunchiPhoneSimulatorLauncher;
"param_runnable_productType" = "com.apple.product-type.application";
"param_testing_launchedForTesting" = 0;
"sdk_canonicalName" = "iphonesimulator27.2";
}
System Information
macOS Version 27.2.1 (Build 26B131)
Xcode 27.2 (25400.63.5) (Build 27B52)
Suggested fix
Replace the [ ... ( =~ ) ] test with something ksh accepts. For example, skip by name:
(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
"$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
case "$fwork" in *_Testing_CoreTransferable.framework) continue;; esac
TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
if [ -f "$fwork/Info.plist" -a ! -d "$TESTING_COPIED" ]; then
...
A sturdier fix wouldn't depend on a framework's name, so it keeps working once Apple fixes the plist or another overlay gets the same problem. It would skip any framework whose CFBundleIdentifier is already in the app:
SEEN_IDS=""
(cd "$PRODUCTS_DIR" && for fwork in $TESTING_FRAMEWORKS \
"$PLATFORM_DEVELOPER_LIBRARY_DIR"/Frameworks/_Testing_*.framework; do
[ -f "$fwork/Info.plist" ] || continue
ID=$(/usr/libexec/PlistBuddy -c 'Print CFBundleIdentifier' "$fwork/Info.plist" 2>/dev/null)
case " $SEEN_IDS " in *" $ID "*) echo "Skipping $fwork: duplicate bundle id $ID"; continue;; esac
SEEN_IDS="$SEEN_IDS $ID"
TESTING_COPIED="$CODESIGNING_FOLDER_PATH/Frameworks/$(basename "$fwork")"
if [ ! -d "$TESTING_COPIED" ]; then
...
Running ksh -n copy_bundle.sh in CI or before a release would also catch syntax errors like this one.
Workaround for users
Until a fixed release ships, either quit InjectionNext and move it out of /Applications, or delete the copied _Testing_CoreTransferable.framework from the built app before it's installed. Then do a Clean Build Folder (⇧⌘K) once, because frameworks already copied into the app stay there until you clean.
- Lenguaje dominante
- Swift
- Estrellas
- 443
- Forks
- 31
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de johnno1962/InjectionNext
-
Duplicate CFBundleIdentifier in copied _Testing_* overlay frameworks breaks simulator installAbierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
johnno1962/InjectionNext#175 · 4 comentarios ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 48/100
johnno1962/InjectionNext#177 · 1 comentario ·
-
First file change after a client connects is not injected (restartLastWatcher backdate consumes it)Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 64/100
johnno1962/InjectionNext#176 · 3 comentarios ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 56/100
johnno1962/InjectionNext#173 · 2 comentarios ·
-
Dificultad 4/5 3-5 días Aptitud para principiantes 38/100
johnno1962/InjectionNext#147 · 1 comentario ·
Todos los issues de johnno1962/InjectionNext
Issues similares
-
area:infra enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 74/100
axeslasher/Jelly-Shark#352 ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
OneBusAway/onebusaway-ios#1658 ·
Los mantenedores suelen responder en 1 día
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P2
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
steipete/CodexBar#5048 · 1 comentario · 1 reacción ·
Los mantenedores suelen responder en 1 día
-
area: build-and-ci S3: minor
Dificultad 2/5 1-3 horas Aptitud para principiantes 72/100
manaflow-ai/cmux#40559 ·
Los mantenedores suelen responder en 1 día
-
Battery health in the panelAbiertoarea: energy area: panel enhancement
Dificultad 2/5 1-3 horas Aptitud para principiantes 63/100
Pallepadehat/WatchMyBattery#11 ·
Los mantenedores suelen responder en 1 día