This is an automated email from the ASF dual-hosted git repository.

manuelbeck pushed a commit to branch pr-fix-run
in repository https://gitbox.apache.org/repos/asf/cordova-ios.git

commit 6c11df377ff4e1d9c35b65902ca8deb52db61259
Author: Manuel Beck <[email protected]>
AuthorDate: Wed Dec 24 09:14:38 2025 +0100

    fix: run
    
    - Under some circumstances the run on an identifiers like `iPhone-16-Pro, 
18.5" did not work
    - Support identifiers with and without hypens
    - Support targeting a simulator UDID
    - Generated-By: Visual Studio Code Copilot, GPT-5, GPT-5.1-Codex-Max
---
 lib/build.js        | 14 +++++++++++---
 lib/simctlHelper.js | 34 +++++++++++++++++++++++++++++-----
 2 files changed, 40 insertions(+), 8 deletions(-)

diff --git a/lib/build.js b/lib/build.js
index 180889d3..94577f58 100644
--- a/lib/build.js
+++ b/lib/build.js
@@ -154,6 +154,12 @@ module.exports.run = function (buildOpts) {
     }
 
     const projectPath = this.root;
+    // When target includes a runtime (e.g., "iPhone-16-Pro, 18.5"), capture 
it for xcodebuild destination
+    const targetRuntime = (function extractRuntime (target) {
+        if (!target || !target.includes(',')) return null;
+        const parts = target.split(',');
+        return (parts[1] || '').trim() || null;
+    })(buildOpts.target);
     let emulatorTarget = 'iOS Device';
 
     if (buildOpts.target && buildOpts.target.match(/mac/i)) {
@@ -254,7 +260,8 @@ module.exports.run = function (buildOpts) {
             // remove the build output folder before building
             fs.rmSync(buildOutputDir, { recursive: true, force: true });
 
-            const xcodebuildArgs = getXcodeBuildArgs(projectPath, 
configuration, emulatorTarget, buildOpts);
+            // Pass targetRuntime so simulator destination can pin the 
requested OS version
+            const xcodebuildArgs = getXcodeBuildArgs(projectPath, 
configuration, emulatorTarget, buildOpts, targetRuntime);
             return execa('xcodebuild', xcodebuildArgs, { cwd: projectPath, 
stdio: 'inherit' });
         }).then(() => {
             if (!buildOpts.device || buildOpts.catalyst || buildOpts.noSign) {
@@ -327,7 +334,7 @@ module.exports.run = function (buildOpts) {
  * @param  {Object}  buildConfig    The build configuration options
  * @return {Array}                  Array of arguments that could be passed 
directly to spawn method
  */
-function getXcodeBuildArgs (projectPath, configuration, emulatorTarget, 
buildConfig = {}) {
+function getXcodeBuildArgs (projectPath, configuration, emulatorTarget, 
buildConfig = {}, targetRuntime = null) {
     let options;
     let buildActions;
     let settings;
@@ -394,9 +401,10 @@ function getXcodeBuildArgs (projectPath, configuration, 
emulatorTarget, buildCon
                 '-destination', customArgs.destination || 
'generic/platform=macOS,variant=Mac Catalyst'
             ]);
         } else {
+            const osPart = targetRuntime ? `,OS=${targetRuntime}` : '';
             options = options.concat([
                 '-sdk', customArgs.sdk || 'iphonesimulator',
-                '-destination', customArgs.destination || `platform=iOS 
Simulator,name=${emulatorTarget}`
+                '-destination', customArgs.destination || `platform=iOS 
Simulator,name=${emulatorTarget}${osPart}`
             ]);
         }
 
diff --git a/lib/simctlHelper.js b/lib/simctlHelper.js
index 5b90890b..d9b26414 100644
--- a/lib/simctlHelper.js
+++ b/lib/simctlHelper.js
@@ -229,16 +229,40 @@ function getDeviceFromDeviceTypeId (deviceTypeId = null) {
         runtimeRaw = null
     ] = deviceTypeId?.split(',') ?? [];
 
+    // Extract the segment after the SimDeviceType prefix (if present)
+    const prefix = 'com.apple.CoreSimulator.SimDeviceType.';
+    const rawWithoutPrefix = (deviceTypeRaw || 
'').trim().replace(/^com\.apple\.CoreSimulator\.SimDeviceType\./, '');
+
+    // If the target is a Simulator UDID (UUID), support selecting by UDID 
directly
+    // UUID pattern: 8-4-4-4-12 hex characters
+    const uuidPattern = 
/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/;
+    if (uuidPattern.test(rawWithoutPrefix)) {
+        const udid = rawWithoutPrefix.toUpperCase();
+
+        for (const deviceGroup of Object.keys(list.devices)) {
+            const normalizedRuntimeName = fixRuntimeName(deviceGroup);
+            const match = list.devices[deviceGroup].find(d => (d.udid || 
'').toUpperCase() === udid);
+            if (match) {
+                return { name: match.name, id: match.udid, runtime: 
normalizedRuntimeName };
+            }
+        }
+
+        throw new Error(`Simulator with UDID "${rawWithoutPrefix}" could not 
be found.`);
+    }
+
     const deviceType = (function normalizeDeviceType (dt) {
-        const prefix = 'com.apple.CoreSimulator.SimDeviceType.';
-        dt = dt.trim();
-        return dt.includes(prefix) ? dt : `${prefix}${dt}`;
+        let val = (dt || '').trim();
+        if (!val) return null;
+        // Ensure identifier form uses hyphens (e.g., "iPhone-16-Pro-Max")
+        const hasPrefix = val.startsWith(prefix);
+        const body = (hasPrefix ? val.slice(prefix.length) : 
val).replace(/\s+/g, '-');
+        return `${prefix}${body}`;
     })(deviceTypeRaw);
 
     // Find the devicename from the devicetype
-    const foundedDeviceType = list.devicetypes.find(d => d.identifier === 
deviceType);
+    const foundedDeviceType = deviceType && list.devicetypes.find(d => 
d.identifier === deviceType);
     if (!foundedDeviceType) {
-        throw new Error(`Device type "${deviceType}" could not be found.`);
+        throw new Error(`Device type "${deviceTypeRaw}" could not be found.`);
     }
     const deviceName = foundedDeviceType.name;
 


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to