Xcode6: Run two instances of the simulator

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:

You can run multiple instances of simulator for different hardware profiles and debug them. First, you need to run your app from XCode for each hardware type (iPhone 6, iPad etc.) to install it into simulator instances. Then run simulator instances and your app as it is explained above. To debug it, you can attach debugger to running processes from "XCode->Debug->Attach to Process" menu. You can check this blog entry for an example :http://oguzdemir.dualware.com/?p=43