From 5d05df04fa2ee06c13b1c7710bae57c86a47d3ec Mon Sep 17 00:00:00 2001 From: Greg Dennezz Date: Fri, 28 Mar 2025 17:47:04 +0100 Subject: [PATCH 1/3] Prefer currently booted iOS Simulator Updated XCodeHelper.getSimulatorID to check for a currently booted simulator via `xcrun simctl list devices booted` before falling back to project target flags or default logic. This improves behavior when switching simulators manually in the Simulator app. --- src/lime/tools/XCodeHelper.hx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/lime/tools/XCodeHelper.hx b/src/lime/tools/XCodeHelper.hx index 7abd0c08dd..1d335ea712 100644 --- a/src/lime/tools/XCodeHelper.hx +++ b/src/lime/tools/XCodeHelper.hx @@ -54,6 +54,21 @@ class XCodeHelper return id; } + public static function getBootedSimulatorID():String + { + // attempts to find a simulator which is currently booted and running + var result = System.runProcess("", "xcrun", ["simctl", "list", "devices", "booted"]); + var lines = result.split("\n"); + for (line in lines) { + // Match a line like: " iPhone 15 Pro (E5B048F6-BE70-498E-B5F6-B84B8594DDBF) (Booted)" + var match = ~/.*\(([A-F0-9\-]{36})\)\s+\(Booted\)/; + if (match.match(line)) { + return match.matched(1); + } + } + return null; + } + public static function getSelectedSimulator(project:HXProject):SimulatorInfo { var output = getSimulators(); @@ -173,6 +188,15 @@ class XCodeHelper public static function getSimulatorID(project:HXProject):String { + // try and get the simulator which is currently open and running + // if there are none running then fall back to getting the selected simulator + var booted = getBootedSimulatorID(); + if (booted != null) + { + // we found a running simulator, so use that + return booted; + } + var simulator = getSelectedSimulator(project); if (simulator == null) { From 97935a5a1b0b774145d37e915c959a55104e3b8c Mon Sep 17 00:00:00 2001 From: Greg Denness <72026480+gregdenness@users.noreply.github.com> Date: Mon, 31 Mar 2025 12:18:39 +0100 Subject: [PATCH 2/3] cleaned up code to be more consistent getBootedSimulator now uses the same logic to match simulator name as elsewhere and also returns SimulatorInfo. getSimulatorName now returns the booted simulator name. --- src/lime/tools/XCodeHelper.hx | 43 +++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/src/lime/tools/XCodeHelper.hx b/src/lime/tools/XCodeHelper.hx index 1d335ea712..f3c861ecf4 100644 --- a/src/lime/tools/XCodeHelper.hx +++ b/src/lime/tools/XCodeHelper.hx @@ -54,21 +54,20 @@ class XCodeHelper return id; } - public static function getBootedSimulatorID():String + private static function getBootedSimulator():SimulatorInfo { - // attempts to find a simulator which is currently booted and running var result = System.runProcess("", "xcrun", ["simctl", "list", "devices", "booted"]); var lines = result.split("\n"); - for (line in lines) { - // Match a line like: " iPhone 15 Pro (E5B048F6-BE70-498E-B5F6-B84B8594DDBF) (Booted)" - var match = ~/.*\(([A-F0-9\-]{36})\)\s+\(Booted\)/; - if (match.match(line)) { - return match.matched(1); + for (line in lines) + { + if (line.indexOf("(Booted)") > -1) + { + return { id: extractSimulatorID(line), name: extractSimulatorFullName(line) }; } } return null; } - + public static function getSelectedSimulator(project:HXProject):SimulatorInfo { var output = getSimulators(); @@ -190,29 +189,35 @@ class XCodeHelper { // try and get the simulator which is currently open and running // if there are none running then fall back to getting the selected simulator - var booted = getBootedSimulatorID(); - if (booted != null) + var simulator = getBootedSimulatorID(); + if (simulator != null) { // we found a running simulator, so use that - return booted; + return simulator.id; } - var simulator = getSelectedSimulator(project); - if (simulator == null) + simulator = getSelectedSimulator(project); + if (simulator != null) { - return null; + return simulator.id; } - return simulator.id; + return null; } public static function getSimulatorName(project:HXProject):String { - var simulator = getSelectedSimulator(project); - if (simulator == null) + var simulator = getBootedSimulatorID(); + if (simulator != null) { - return null; + return simulator.name; } - return simulator.name; + + simulator = getSelectedSimulator(project); + if (simulator != null) + { + return simulator.name; + } + return null; } private static function getSimulators():String From 66a5bf8aa04b4147be9deef6e47d2668be377e97 Mon Sep 17 00:00:00 2001 From: Greg Denness Date: Mon, 31 Mar 2025 13:11:02 +0100 Subject: [PATCH 3/3] fixed a bug with extractSimulatorID It appears that modern simulators have started adding their CPU types to their names, "like iPad Air (M4)" which was causing the exiting code to return the incorrect string for the ID (it would return 'M4' as the ID in that case). I fixed this by searching for ID's which are specifically 36 chars long which is the format the ID's follow. I think this probably would have affected the code in the current release version of lime? --- src/lime/tools/XCodeHelper.hx | 67 +++++++++++++++++++++-------------- 1 file changed, 41 insertions(+), 26 deletions(-) diff --git a/src/lime/tools/XCodeHelper.hx b/src/lime/tools/XCodeHelper.hx index f3c861ecf4..e268ae6aa4 100644 --- a/src/lime/tools/XCodeHelper.hx +++ b/src/lime/tools/XCodeHelper.hx @@ -43,15 +43,35 @@ class XCodeHelper private static function extractSimulatorID(line:String):String { - var id = line.substring(line.indexOf("(") + 1, line.indexOf(")")); - - if (id.indexOf("inch") > -1 || id.indexOf("generation") > -1) + // Simulator ID's are always: + // XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + var searchPos = 0; + + while (true) { - var startIndex = line.indexOf(")") + 2; - id = line.substring(line.indexOf("(", startIndex) + 1, line.indexOf(")", startIndex)); + var openParen = line.indexOf("(", searchPos); + var closeParen = line.indexOf(")", openParen); + + if (openParen == -1 || closeParen == -1) + { + // Couldn't find a valid ID + break; + } + + var potentialID = line.substring(openParen + 1, closeParen); + + // Simulator IDs are always UUID strings exactly 36 chars long + if (potentialID.length == 36 && potentialID.indexOf("-") > -1) + { + return potentialID; + } + + // Skip past the current set of parentheses and keep looking + searchPos = closeParen + 1; } - - return id; + + // No valid ID found + return ""; } private static function getBootedSimulator():SimulatorInfo @@ -62,7 +82,7 @@ class XCodeHelper { if (line.indexOf("(Booted)") > -1) { - return { id: extractSimulatorID(line), name: extractSimulatorFullName(line) }; + return { id: extractSimulatorID(StringTools.trim(line)), name: extractSimulatorFullName(StringTools.trim(line)) }; } } return null; @@ -187,35 +207,30 @@ class XCodeHelper public static function getSimulatorID(project:HXProject):String { - // try and get the simulator which is currently open and running - // if there are none running then fall back to getting the selected simulator - var simulator = getBootedSimulatorID(); - if (simulator != null) - { - // we found a running simulator, so use that - return simulator.id; - } - - simulator = getSelectedSimulator(project); - if (simulator != null) - { - return simulator.id; - } - return null; + var simulator = getPreferredSimulator(project); + return (simulator != null) ? simulator.id : null; } public static function getSimulatorName(project:HXProject):String { - var simulator = getBootedSimulatorID(); + var simulator = getPreferredSimulator(project); + return (simulator != null) ? simulator.name : null; + } + + private static function getPreferredSimulator(project:HXProject):SimulatorInfo + { + // try and get the simulator which is currently open and running + // if there are none running then fall back to getting the selected simulator + var simulator = getBootedSimulator(); if (simulator != null) { - return simulator.name; + return simulator; } simulator = getSelectedSimulator(project); if (simulator != null) { - return simulator.name; + return simulator; } return null; }