As of Xcode 6, you should be able to use simctl
to accomplish this.
1) Get the list of available devices:
xcrun simctl list devices
1a) Assuming you have jq
installed, you can use it to get only those devices that are actually available:
xcrun simctl list devices -j \
| jq -rc '.[] | .[] | .[] | select( .availability | contains( "(available)" ) ) '
1b) Or even filter further by iPhone or iPad:
xcrun simctl list devices -j \
| jq -rc '.[] | .[] | .[] | select( .name | contains( "iPhone" ), contains( "iPad" ) ) | select( .availability | contains( "(available)" ) ) '
2) Once you have the UDID of the device you want to install to:
xcrun simctl install $DEVICE_UDID /path/to/your/app
2a) Or, if you want to just install to the booted device:
xcrun simctl install booted /path/to/your/app
Where this gets really handy is if you want to run the same app on all the devices:
1) Reset / erase all simulators:
xcrun simctl erase all
2) Open one Simulator instance for each test:
open -n /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app
(Ignore the 'Booted' error and switch hardware.)
3) Get UDIDs of available devices we want to install to:
DEVICES=$( xcrun simctl list devices -j | jq -rc '.[] | .[] | .[] | select( .name | contains( "iPhone" ), contains( "iPad" ) ) | select( .availability | contains( "(available)" ) ) | select( .state == "Booted" ) | .udid ' )
4) Install the app (which must be built for the appropriate simulator SDK):
for device in DEVICES ; do xcrun simctl install $device /path/to/app ; done
5) For convenience, launch the app on each device:
for device in $DEVICES ; do xcrun simctl launch $device your.product.app.id ; done