Have you ever had to work on an universal iOS app and confirm the app builds correctly on multiple OS versions? As Apple continues to produce new devices and iOS, supporting your application across combinatory schemes can get hairy. Depending on the device and version of iOS that is running, margins and layouts may look different, animations may function differently, and constraints may not behave as intended. Luckily, in Xcode 9, Apple has enabled developers to launch multiple simulators without shutting down the previous debugging session. This is a great tool enabling you to launch each simulator side by side for view comparison. However, there are certain inconveniences that arise in use. For instance, when you are compiling a monolithic codebase, it can be a tedious and time consuming process. Alternatively, it can be easy to launch a certain combination of simulator and iOS and miss view inconsistencies.

What if we can compile once and launch a set of simulators of your choosing simultaneously? Building once and launching on a given set of simulators altogether would save a great deal of time and remove the need to remember which simulator and iOS combination needs to be tested. With a little bit of shell scripts, anything is possible!

Create a new simulator named “Custom Simulators” in the pre-action build script

In Xcode, edit a scheme and add a Pre-actions script to the Build option by selecting the + button on the bottom left.

The pre-action script creates a simulator named “Custom Simulators” with a device type of iPhone X running on the latest iOS runtime, if your Xcode environment does not contain one. Close the window and build your project. You should now see the new simulator in your drop down list.

2. Create a MultiSimConfig.txt file in the root directory of your project. This file specifies which simulators to launch with the “Custom Simulators” set. To list the available devices you can choose from, execute the following on a terminal.

instruments -s devices

Example of MultiSimConfig.txt

3. Create a script that consumes MultiSimConfig.txt and launch the simulators specified in it.

Stick this script in the root directory of the project or a specific scripts folder if you have one. Replace ${project_name} with your project’s name, replace ${app_name} with the name of the .app executable file from your derived data (typically it is the name of your target, you can always double check the variables by checking your path to the derived data folder). And lastly replace ${bundle_identifier} with the name of your project’s bundle identifier. The script begins by shutting down any simulators you have opened, locates the app’s executable file in your derived data, reads your MultiSimConfig file, and loops each simulator from the file to install the executable app file and launches it.

4. Our final step is to wire up your project to this script on the post build action.

Select your project's target -> select Build Phases -> add New Run Script Phase from the drop down and add the following script in the editor

This script saves the UUID of your “Custom Simulators” to a custom_sim variable and executes your launch_multiple_simulators.sh script if the current target device matches your “Custom Simulators” UUID.

And there you have it! Build and run your project with the “Custom Simulators” selected. You should see all the simulators specified in your config file launch. As you remember, we specified iPhone-X as the default simulator which will launch every time you run the project with the new simulator. If you prefer to run without the default, simply build without a run and all your specified simulators will launch. Also be sure your project’s deployment target is ≤ to the specified simulator’s iOS otherwise your simulators will not install the app. Happy coding!

Open source: https://github.com/ginowu7/CustomSimulatorsExample