Xcode6: Run two instances of the simulator

55,778

Solution 1

You can run two instances of the iOS simulator from the command line. They won’t be attached to Xcode debugging—indeed, it seems only to work if you do it without Xcode running at all.

First, you need to run the app in the simulator from Xcode, in order to get it installed in the simulator. Make sure you’re running the same simulators you’ll ultimately be using

Now open a Terminal window, and do this.

cd /Applications/Xcode.app/Contents/Developer/Applications
open -n iOS\ Simulator.app
open -n iOS\ Simulator.app

Update for Xcode 7: With Xcode 7 the application name of the simulator has changed, so it's this instead:

cd /Applications/Xcode.app/Contents/Developer/Applications
open -n Simulator.app
open -n Simulator.app

When the second one launches you’ll get an error alert. Just dismiss it and select a different device from “Hardware” » “Device”. Now you have two simulators running, and whatever apps you already installed in them from Xcode will be there.

Solution 2

Xcode 9+

Xcode 9 now supports launching multiple simulators. This was announced in WWDC 2017.

Just go and change the simulator in Xcode, Cmd + R and you will see a new simulator popping up.

enter image description here

Solution 3

Successfully tested that i40west's solution works to manually launch simulator but seems silly that in this day and age, an iOS simulator requires different Xcode versions AND different device types when running concurrent tests from command line (slightly different use case but related to original question at top).

Refer to the Apple article here which is most relevant for command line builds and tests: https://developer.apple.com/library/ios/technotes/tn2339/_index.html

Multiple concurrent tests has worked fine for us if passing correct --args -- to 'iOS simulator.app' before running the 'xcodebuild test' command with correct '-destination' value matching simultator launch with value of UUID from output of 'xcrun simctl list', and setting DEVELOPER_DIR environment variable to select different XCode version binaries (i.e. base path to Xcode 6.1 and 6.4)

Reason for needing concurrent unit tests on same physical machine and same iOS simulator device such as iPad or iPhone and same Xcode version is primarily to support CI (continuous integration) of any iOS project whereby the same build system can run more than 1 build of multiple apps (our company has 30 apps or so) at a time upon check-in on feature branches are automatically scanned and built by Bamboo agent without needing to wait for other running Builds to complete -- Bamboo supports this type of auto build on auto-discovered feature branches if enabled.

As for what happens when running multiple concurrent tests, we run multiple 'xcodebuild test' commands twice in succession in different Terminal.app windows, the result is only one simulator window appears and tests fail in the simplest test.

When we complicate the entry criteria for our test launch, different Xcode versions for each sim and test launch, when using DEVELOPER_DIR as per man pages (xcodebuild test) we are specifying a different device which open in two separate windows, but the result is that any running tests in first window are interrupted by second iOS simulator window.

There seems to be a common shared resource under the hood that is getting in the way, not sure it is intended or just a new feature that requires more than a few days of serious thought in how to better implement concurrent test runs wihout adverse impacts.

We don't want to use VMs to work around the sim restrictions as our experience and of others in general is that iOS build performance on VMs with large number of small files is slower than physical hardware. VMs generally will slow the build down by a lot due to I/O issues in the combination of VMware software and Apple hardware and/or firmware. Sorry virtuallyghetto but for us VMs don't perform well -- the virtuallyghetto site has provided us instructions on how to install ESXi 5.5 on Mac Mini's for our build farm.

We have experienced the build performance issue with ESXi 5.5 on Mac Mini being slower than bare metal even with SSD by a factor of 2 or more (i.e. a 10 minute baremetal build takes 20 on VM). Refer to squareup article below on why.

https://corner.squareup.com/2015/07/ios-build-infrastructure.html

The restriction of 1 sim device at a time for xcodebuild unit tests severely reduces productivity and exponentially adds significant costs to Apple and the ecosystem.

The cost to Apple of not supporting concurrency to justify more hardware purchases should be thought of carefully, weighing risks of losing developer velocity against other competitors who have less restrictions in terms of sims and EULA.

The advantage of concurrent tests in same user login (how most ci systems work) is that quality of Apple branded app store apps which in turn is in part what makes people buy the iOS devices in the first place. Poor software quality makes the whole brand a bit more slugish and concurrency support in iOS simulators definitely seems like the smart way to go to support the ecosystem. A bit of a corollary to the issue at hand are recent improvements such as Apple's Xcode server for CI, Xcode's automated UI tests functionality in Xcode 7.

Encouraging needless overheads to make people buy mass quantities of hardware, setup, configuration, not to mention numerous people required to support all the machines, network and power points, etc, will potentially harm Apple's profits in the end as not everyone is like Apple and able to afford racks of MacPro's or Mac Mini's just to support concurrent tests on simulators. The whole point of a simulator is to avoid using the hardware and also speeding up the tests.

Plus the EULA limitations on VMs makes the case for VMs on Mac Pro's quite weak. This hardware type would be attractive if multiple sims could run but since concurrent unit tests isn't supported (except in above two conditions - different XCode version and different simulator device) we will likely stick with Mac Mini's for build infrastructure.

These sim and EULA limitations from Apple not only make the build pipeline slower but also add unnecessary complexity and cost. It may not be so concerning for small apps but as the apps grow in size and complexity, the build can take upwards of an hour (I heard that Facebook iOS builds can take that long). Nobody wants to wait an hour to know if a build passed.

We know of hack solutions like running ESXI VMs on Mac Minis which don't play well performance wise with OS X and xcodebuild on large projects with builds that take more than 10 minutes on a modern Mac Book Pro or Mac Mini, or different login accounts on bare metal machine to the environment just to be able to run concurrent tests on same Xcode version and same simulator device.

ESXi is not officially supported although it works pretty well. One of the reasons VMware might not support Mac Mini hardware yet is lack of ECC memory, although Mac Pro is supported as it does have ECC memory, it likely has same issues as the Mac Mini's in terms of iOS builds slow down compared to bare metal tests on same hardware and software config (only change is VM versus bare metal running OS X). MacPro has not been tested by us at this time. In our experience VMware Fusion is quite slow in terms of performance as well.

More importantly developers will need to wait longer when aforementioned issues are compounded together unless the pool of machines is large enough to support pipleline of changes (one CI build for every 2 devs, very high ratio of machines to developer). CI build machines should be able to run more concurrent Builds and more concurrent tests than 1.

One of the other observations about the iOS simulators is that they seem to be a work in progress and completely unfinished even after 7 major versions. The 'xcrun simctl' subcommand has a --set option which may allow some flexibility of some kind but not sure of what possible value is valid, and same with --noxpc. Nobody should need to guess appropriate values and furthermore, there should be a man page that covers this option and and perhaps example. What are some use cases for these 2 interesting options?

You may say, well no app should be designed to have a large footprint that warrants concurrent test to run, and making use of better architecture based on XPC, as monolithic apps are the issue. This may very well be correct, it is not as pragmatic solution as we could hope for, and the issue remains if you have 20+ apps to build on same infrastructure.

Making a machine configuration and processes as generic and scalable as possible for higher throughput will require some work on the simulator (app + core devs). It also requires a high level of collaboration between all Apple simulator developers and the simulator product owner(s) needs to order the product backlog correctly for this issue to get any attention :-)

Solution 4

FBSimulatorControl from Facebook provides a programmatic way to do this. It's available at https://github.com/facebook/FBSimulatorControl.

The method testLaunchesMultipleSimulatorsConcurrently in FBSimulatorControlSimulatorLaunchTests.m has sample code illustrating how to launch multiple simulators.

Solution 5

here a little script in .sh to list UDID of simulators on your computer and run it. Copy the code below in a file with extension ".sh" and run it in terminal.

How to:

Step 1. List devices with option 1 and copy the UDID wanted

Step 2. Run option 2 and paste the UDID then press enter key

Be careful: verify that the path which contains your simulators is ok (if not replace by your path)

#!/bin/sh
PS3='Type the number of your choice (1, 2 or 3) and press Enter: '
options=("List Devices" "Run Simulator" "Quit")
select opt in "${options[@]}"
do
    case $opt in
        "List Devices")
            xcrun simctl list devices
            echo "\033[1m\n\nCopy the UDID in parentheses of the device which you want run and launch option 2 (Run Simulator)\033[0m"
            ;;
        "Run Simulator")
            read -p 'Type device UDID which you want launch: ' currentDeviceUDID
            open -n /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/ --args -CurrentDeviceUDID $currentDeviceUDID
            ;;
        "Quit")
            break
            ;;
        *) echo invalid option;;
    esac
done

Thank you,

Share:
55,778
vintagexav
Author by

vintagexav

Tech entrepreneur in Silicon Valley focused on Python and PostgreSQL. I did lots of Node, iOS and iBeacons before, and have always been doing PG, and a bit of Redis and Mongo.

Updated on May 19, 2020

Comments

  • vintagexav
    vintagexav about 4 years

    I have two different targets for my iOS app. Is it possible to run simultaneously the two apps on two different instances of the simulator? It's ok if it would require not to benefit of the Xcode's debugger. So far the only solution I found was to install two versions of XCode, but that's a very heavy/space-consuming solution.

  • vintagexav
    vintagexav over 9 years
    Hey Thanks, that's a good idea, but unforunately it says "Unable to boot device in current state: Booted" for the second simulator. I see two simulators but the screen of the second one stays black even after dimissing the alert.
  • Jeremy
    Jeremy over 9 years
    That’s the error alert I was talking about. After I dismiss it, my second simulator boots. If yours doesn’t, I have no idea why.
  • vintagexav
    vintagexav over 9 years
    Maybe that's because my XCode is currently running. Maybe you should add that instruction to your answer :) Also it works only if using two different simulated hardwares (eg: iPhone 5 and iPhone 5s)
  • Jeremy
    Jeremy over 9 years
    Ah! I indeed tried it without Xcode running. I’ll update my answer.
  • vintagexav
    vintagexav over 9 years
    By the way, to run two different simulators properly with two different simulated hardwares and avoid the "Unable to boot device in current state: Booted", you have to change the version of the first simulator after starting it by clicking on simulator>hardware. More info: stackoverflow.com/questions/24023029/…
  • ObjectiveTC
    ObjectiveTC over 9 years
    Thanks! I am using 2 simulators (one running iPhone5, the other iPhone6) to test iCloud syncing. To note, the Simulator's sync'ing is finicky, so for practical purposes you must force the iCloud sync using Debug->Trigger iCloud Sync. So with these two devices running my application in their separate simulator windows, I make a change on device1 (iphone5), force sync for device1, the click over to device2 (iPhone6) and force sync. And viola, you can now test iCloud syncing in simulator. Opening simulator's Console is helpful, as you can view background sync activity when it happens.
  • Alex
    Alex over 9 years
    I'm glad I found your answer, thank you! Just wanted to mention that apparently you CAN have XCode running at the same time, with the following caveats: 1. the second simulator has to have a different configuration than the first one (after the popup complaining, you need to change the simulator's device version from Hardware menu). 2. whenever you stop and restart the first simulator from XCode, the second one will also be stopped and restarted (and you'll need to change it's device version again)
  • abbood
    abbood almost 9 years
    hey i40West great answer.. there is one part that i was wondering if we could automate (my ultimate goal is running a shell script that basically runs a specific app on several simulators.. without ever having to do anything on xcode).. is there a way to do this part you need to run the app in the simulator from Xcode, in order to get it installed in the simulator by command line? I know you can use the xcodebuild CLI, but i'm not sure how to link that to a specific simulator
  • Jeremy
    Jeremy almost 9 years
    @abbood According to the documentation, xcodebuild supports a -destination option that lets you specify a particular simulator. I haven't tried it but that looks like what you're looking for.
  • Radu Simionescu
    Radu Simionescu almost 9 years
    the "iOS\" parameter for the open command should be removed. It worked after removing that
  • Jeremy
    Jeremy almost 9 years
    @RaduSimionescu That seems to be an Xcode 7 change. Will update.
  • Nick
    Nick over 8 years
    As of Xcode 7, Location only seems to work with 1 simulator at a time. You have to open an a 3rd simulator to adjust the location on the second. The first will be "locked in". Still helpful if you just need to set location once for each simulator
  • Priyansh
    Priyansh almost 8 years
    Updated path for Xcode 7.3 cd /Applications/Xcode7.3.app/Contents/Developer/Applications
  • Max MacLeod
    Max MacLeod almost 4 years
    @Sravan please try it and let us know.
  • Sravan
    Sravan almost 4 years
    @MaxMacLeod No. Its not working. I need to end the debug session in one simulator and launch in another simulator. I am using XCode 11.6