How can one run a project on multiple destinations (say, iPhone, iPad and iSimulator) at once?
There are 2 related questions:
- Xcode 4 - One Click Build to Multiple Devices?
- Run on simulator and phone with one click
The 1ˢᵗ question (supposedly) has an answer, but I can't figure out how exactly should you use the Aggregate
target (if this is the right direction at all), and apparently neither could Josh Kahane, the OP; the "answer" still somehow got/remained accepted.
The 2ⁿᵈ question was closed down as a "duplicate", as if the 1ˢᵗ one provided a (workable) answer.
Added a bounty: (how) can one use Aggregate
target for simultaneous, multiple Build & Run
? Perhaps one can achieve simultaneous, multiple Build & Run
via some .sh
script using xcodebuild
? Any other possible solution?
I ran into the same issue, so I wrote an Xcode plugin to help out with this. I found it to be more robust and easier to invoke than the AppleScript options.
The plugin is called KPRunEverywhereXcodePlugin and is available via Alcatraz or on GitHub: https://github.com/kitschpatrol/KPRunEverywhereXcodePlugin
Hope this helps!
It's actually simpler than I thought. This AppleScript
puts some pain out of Xcode
:
tell application "Xcode"
activate
end tell
tell application "System Events"
tell application process "Xcode"
click menu item "1st iDevice Name" of menu 1 of menu item "Destination" of menu 1 of menu bar item "Product" of menu bar 1
click menu item "Run" of menu 1 of menu bar item "Product" of menu bar 1
delay 5
click menu item "2nd iDevice Name" of menu 1 of menu item "Destination" of menu 1 of menu bar item "Product" of menu bar 1
click menu item "Run" of menu 1 of menu bar item "Product" of menu bar 1
delay 5
click menu item "iPhone 6.1 Simulator" of menu 1 of menu item "Destination" of menu 1 of menu bar item "Product" of menu bar 1
click menu item "Run" of menu 1 of menu bar item "Product" of menu bar 1
end tell
end tell
- Save the above
AppleScript
as an .app
. (Customize delay
s to your machine.)
- Create a new
Service
in Automator
: choose Launch Application
and select the .app
from previous step.
- Save
Service
from previous step and give it a keyboard shortcut. Tip: avoid shortcuts with ^, since it will bring up this dialog:
Granted, this isn't strictly a simultaneous 'Build & Run', but it sure beats manually trifling between destinations.
Here is a script that will build and run on all connected iOS devices. To use:
- Open "Automator".
- Create a new "Quick Action".
- Select "no input" for "Workflow receives".
- Select Xcode for the application.
- Add a "Run JavaScript" action and paste the script.
- Save as "Run on All", you can now access this from the Xcode -> Services menu from Xcode.
Javscript:
function run(input, parameters)
{
var xcode = Application("Xcode");
var ws = xcode.activeWorkspaceDocument();
var genericDest = null;
var devices = [];
ws.runDestinations().forEach(function(runDest)
{
if (runDest.platform() != "iphoneos")
return;
if (runDest.device().generic())
{
genericDest = runDest;
}
else
{
devices.push(runDest);
}
});
devices.forEach(function(device)
{
ws.activeRunDestination = device;
var buildResult = ws.run();
while (true)
{
if (buildResult.completed())
break;
if (buildResult.buildLog() && buildResult.buildLog().endsWith("Build succeeded\n"))
break;
delay(1);
}
delay(1);
});
}
It would indeed be nice to have multiple uploads at once with Xcode. However as I understand it, aggregate
only allows you to compile multiple targets, not run them.
Given the second part of you question (after the edit) I can point you to another way to do it. You won't have xcode attached (but gdb in console mode) and you should be able to make it simultaneous on several device, although this was not the primary goal. This particular solution doesn't work with simulator, but there are other methods for those.
launching iOS App from Mac OS X console
Here's a script that will run all of the devices currently available in your Product -> Destination menu. NB: it relies on the following conditions:
- Devices are selected from the Product -> Destination menu (could change in future versions of Xcode)
- The menu item before your devices is named "My Mac 64-bit" (could change in future versions of Xcode)
The menu item after your devices is named "iOS Simulator" (guess when that might change?)
tell application "Xcode"
activate
end tell
tell application "System Events"
tell process "Xcode"
set deviceMenu to menu 1 of menu item "Destination" of menu 1 of menu bar item "Product" of menu bar 1
set allUIElements to entire contents of deviceMenu
set startAfterName to "My Mac 64–bit"
set stopName to "iOS Simulator"
set started to false
repeat with anElement in allUIElements
try
set menuName to name of anElement
if menuName is equal to stopName then
set started to false
exit repeat
else if menuName is equal to startAfterName then
set started to true
else if started then
click menu item menuName of menu 1 of menu item "Destination" of menu 1 of menu bar item "Product" of menu bar 1
click menu item "Run" of menu 1 of menu bar item "Product" of menu bar 1
delay 5
end if
end try
end repeat
end tell
end tell