Skip to content

Commit 1dd54cf

Browse files
committed
[[ Bug 22960 ]] Use simctl to deploy to iOS simulator
This patch uses the simctl tool to deploy to iOS simulator. This approach is more stable than the mothods used in the reviphoneproxy external, and also fixes a number of issues such as deployment when the simulator is not up and running, or deployment when the simulator app is open but no device is booted. Tested with iOS 13.3 and iOS 14.1 simulator, in all possible combinations of the simulator status.
1 parent df34a44 commit 1dd54cf

File tree

1 file changed

+104
-14
lines changed

1 file changed

+104
-14
lines changed

ide-support/revdeploylibraryios.livecodescript

Lines changed: 104 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -272,15 +272,111 @@ command deployDo pTargetStack, pSimulator, pAppBundle
272272
revStandaloneProgress "Launching app..."
273273

274274
put empty into sDeploySimulationStatus
275-
try
276-
revIPhoneLaunchAppInSimulator tTempAppBundle, tFamily, "revIDEDeployIOSLaunchCallback"
277-
catch tException
278-
end try
279275

280-
--MM-2011-09-28: The simulator appears to time out in Lion if not at front.
281-
--
282-
--get "tell application" && quote & "iPhone Simulator" & quote & "to activate"
283-
--do it as "applescript"
276+
local tListDeviceCommand, tCheckIfSimulatorIsOpenCommand, \
277+
tBootedDevice, tSimShouldOpen, tNeedToBootDevice
278+
279+
// Check if Simulator is already up and running
280+
put "ps aux | grep" && quote & "Simulator.app" & quote into tCheckIfSimulatorIsOpenCommand
281+
get shell(tCheckIfSimulatorIsOpenCommand)
282+
if it contains "Simulator.app/Contents/MacOS/Simulator" then
283+
put false into tSimShouldOpen
284+
else
285+
put true into tSimShouldOpen
286+
end if
287+
288+
// Check if there is a booted device
289+
put "xcrun simctl list devices 2>/dev/null | grep" && quote & "Booted" & quote into tListDeviceCommand
290+
get shell(tListDeviceCommand)
291+
put line 1 of it into tBootedDevice
292+
293+
// If Simulator is open and there is a booted device, we are ready
294+
if not tSimShouldOpen and tBootedDevice is not empty then
295+
put "false" into tNeedToBootDevice
296+
put "started" into sDeploySimulationStatus
297+
else if tBootedDevice is empty then
298+
put "true" into tNeedToBootDevice
299+
// find the first available device to boot
300+
put "xcrun simctl list devices 2>/dev/null | grep" && quote & "iOS" && tSimVersion & quote && "-A1 | tail -n 1" into tListDeviceCommand
301+
get shell(tListDeviceCommand)
302+
if the result is not 0 then
303+
throw "Searching for available devices failed with error:" && it
304+
end if
305+
put it into tBootedDevice
306+
end if
307+
308+
/*
309+
The entries are of the form:
310+
311+
-- iOS 12.1 --
312+
iPhone 6 Plus (5FBD7B17-8596-448F-835F-E414BB3D782F) (Shutdown)
313+
-- iOS 13.3 --
314+
iPhone 6s (8DBBE34E-B77F-4B12-9689-6112E2A6F89E) (Shutdown)
315+
iPhone 8 (185BBCC3-3F48-4A49-8AC5-E5E816F70001) (Shutdown)
316+
iPhone 8 Plus (F5E18B6F-A056-4128-97DD-F41C52B875DD) (Booted)
317+
*/
318+
319+
local tUUID, tFound
320+
// extract the UUID
321+
put matchtext(tBootedDevice, "([0-9A-F]{8}-([0-9A-F]{4}-){3}[0-9A-F]{12})", tUUID) into tFound
322+
323+
if tNeedToBootDevice then
324+
// Boot the device
325+
local tBootDeviceCommand
326+
put "xcrun simctl boot" && tUUID into tBootDeviceCommand
327+
get shell(tBootDeviceCommand)
328+
if the result is not 0 then
329+
throw "Booting available device failed with error:" && it
330+
end if
331+
end if
332+
333+
if tSimShouldOpen then
334+
local tSimulatorAppPath, tCommand
335+
put line 1 of the cMobileSupport["ios.sdks"] of stack "revPreferences" into tSimulatorAppPath
336+
put "/Applications/Simulator.app/" after tSimulatorAppPath
337+
get shell("open" && tSimulatorAppPath && "--args -CurrentDeviceUDID" && tUUID)
338+
if the result is not 0 then
339+
throw "Launching Simulator failed with error:" && it
340+
end if
341+
end if
342+
343+
-- allow some time for the simulator to open
344+
repeat forever
345+
local tBootStatusCommand
346+
put "xcrun simctl bootstatus" && tUUID into tBootStatusCommand
347+
get shell(tBootStatusCommand)
348+
if the result is not 0 then
349+
throw "Checking simulator bootstatus failed with error:" && it
350+
end if
351+
if it contains "Device already booted" then
352+
put "started" into sDeploySimulationStatus
353+
exit repeat
354+
end if
355+
end repeat
356+
357+
// install the app
358+
local tInstallCommand
359+
put "xcrun simctl install booted" && quote & tTempAppBundle & quote into tInstallCommand
360+
get shell(tInstallCommand)
361+
if the result is not 0 then
362+
throw "Installing app failed with error:" && it
363+
end if
364+
365+
// launch the app
366+
local tLaunchCommand, tAppID
367+
put tSettings["ios,bundle id"] into tAppID
368+
if tAppID is empty then
369+
put "com.yourcompany.yourapp" into tAppID
370+
end if
371+
put "xcrun simctl launch booted" && tAppID into tLaunchCommand
372+
get shell(tLaunchCommand)
373+
if the result is not 0 then
374+
throw "Launching app failed with error:" && it
375+
end if
376+
377+
// Bring Simulator app to the front
378+
get "tell application" && quote & "Simulator" & quote & "to activate"
379+
do it as "applescript"
284380

285381
local tRunawayTimer
286382
put the millisecs + 10000 into tRunawayTimer
@@ -336,12 +432,6 @@ end deployDo
336432
command deployBuild pTargetStack, pOutputFolder
337433
end deployBuild
338434

339-
-- This callback is invoked by the iOS simulator interconnect external when
340-
-- the status of a launch request changes.
341-
command revIDEDeployIOSLaunchCallback pStatus
342-
put pStatus into sDeploySimulationStatus
343-
end revIDEDeployIOSLaunchCallback
344-
345435
////////////////////////////////////////////////////////////////////////////////
346436

347437
-- Two iOS simulator versions can't be running at once as they interfere

0 commit comments

Comments
 (0)