simctl: Control iOS Simulators from Command Line

While developing iOS apps, simulators are the best friends of developers. It’s the quick and easy way to test app while development as we can interact with iOS simulators using GUI. Apple’s documentation on getting started in simulator is awesome and we can learn almost everything about controlling simulators from using graphical user interface.

Although, simulators are easy to use with GUI, it’s bit painful to script simulator interactions to run on Continuous Integration server. Fortunately, Apple has nice command line utility called “simctl”.

In this post, let’s see how to use ‘simctl’ to interact with iOS simulators. We will cover following

  • Creating, Deleting and Booting Simulators
  • Adding photos and video to simulators
  • Installing/Uninstalling, launching/Terminating app inside simulator
  • Capturing screenshot and record video of simulator
  • Collecting the simulator logs and other tricks

simctl

Apple has ‘simctl’ binary to interact with iOS simulators from command line. It’s very similar to the adb for Android. Again it’s another utility poorly documented by Apple but we can find binary at /Applications/Xcode.app/Contents/Developer/usr/bin/simctl and we can use it with xcrun utility . We can access all the available options using the help command

$ xcrun simctl help

We can perform various actions on iOS simulator using ‘simctl’ from creating new simulator, erasing simulator, installing app inside simulator, add photo/video to simulator and may more. Let’s look into few of them in details.

Listing all available simulators

We can easily list all the available simulators using command

$ xcrun simctl list

This command will list all the available simulators with runtime. It will also show ‘booted’ simulator if it’s running already.

CRUD operations on Simulators

We can create, erase, delete, boot, shutdown and upgrade simulators using simctl.

Create

We can easily create new simulator called ‘My-iPhone7″ on top of existing iPhone7 (iOS 10.3) simulator using command

$ xcrun simctl create My-iphone7 com.apple.CoreSimulator.SimDeviceType.iPhone-7 com.apple.CoreSimulator.SimRuntime.iOS-10–3

We can see that newly created simulator using list option and we have UUID for the simulator ‘C86A559A-1F50–40D1–8D84–954EDFBBCE18′

Shutdown/Erase/Boot

As we have already seen that, there is another simulator already booted, let’s shut it down and erase it’s content. The order is important here, we can’t erase simulator in the booted state, we need to shutdown first then erase.

$ xcrun simctl shutdown C8C050F3–062D-4444-A888-BBEC783E31BD
$ xcrun simctl erase C8C050F3–062D-4444-A888-BBEC783E31BD

Boot

Now let’s boot the newly created simulator using new UUID

$ xcrun simctl boot C86A559A-1F50–40D1–8D84–954EDFBBCE18

Now that, we have learned how to shutdown, boot and erase simulator. Let open any simulator by using

$ open /Applications/Xcode.app/Contents/Developer/Applications/Simulator.app/

You can see that simulator is booting.

Add Photo/Video to Simulator

An iOS simulator by default has 5 images but we can add more images or video using simctl addmedia functionality. Let’s add one photo(png) and on video(gif) inside our simulator which is kept on desktop.

$ xcrun simctl addmedia booted ~/Desktop/shashi.png

Now, simulator will have another photo. Similarly, we can add video as well.

$ xcrun simctl addmedia booted ~/Desktop/simctl_list.gif

Install/Uninstall app inside Simulator

We can easily install our app inside simulator from command line if we already have path to .app file from derived data. Let’s create new single view app in Xcode and name it “CLI” and save it on desktop. We need to build the app using xcodebuild to get CLI.app in the derived data.

$ xcodebuild build build -scheme “CLI” CODE_SIGN_IDENTITY=”” CODE_SIGNING_REQUIRED=NO

Now, we will get the CLI.app inside derived data, in my case it’s inside /Users/shashi/Library/Developer/Xcode/DerivedData/CLI-dxasphjukowuptcqxzbmyaqgpbqp/Build/Products/Debug-iphoneos/CLI.app directory.

We can install our CLI.app inside simulator using

$ xcrun simctl install booted /Users/shashi/Library/Developer/Xcode/DerivedData/CLI-dxasphjukowuptcqxzbmyaqgpbqp/Build/Products/Debug-iphoneos/CLI.app

Watch the GIF below where we are installing CLI.app

Similarly we can uninstall our iOS app from simulator easily. We need to know the bundle identifier of our app. In my case it’s test.CLI we can uninstall app using

$ xcrun simctl uninstall booted test.CLI

Launch/Terminator app inside Simulator

Similar to installation, we can launch and terminate an app using command line using simctl. We have to make sure app is installed before we launch.

$ xcrun simctl launch booted test.CLI

We can see that app is launched, we can then terminate app using

$ xcrun simctl terminate booted test.CLI

Screenshot and Video Recording of Simulator

In Xcode 8.2, Apple introduced this really nice feature of capturing the screenshot and recording video of the simulator. Now it’s easy to capture screenshot of the simulator. We can capture current state of simulator using

$ xcrun simctl io booted screenshot screen.png

This will save the screenshot of the simulator in the current working directory with file screen.png

Similarly, we can record video of simulator while using app and save it on disk using

$ xcrun simctl io booted recordVideo news.mov

This will save video of the simulator to to news.mov file which can be played using Quick Time player or similar.

Collecting Simulator Logs

Sometime it would be helpful to print the simulator logs as console output. We can easily determine activity of the simulator by reading the logs. Let’s print the logs of simulators

$ xcrun simctl spawn booted log stream — level=debug

we can also filter the log output if you looking for logs of particular app

# filter log output
xcrun simctl spawn booted log stream — predicate ‘processImagePath endswith “CLI”’
xcrun simctl spawn booted log stream — predicate ‘eventMessage contains “error” and messageType == info’
# collect log data
xcrun simctl spawn booted log collect
# open location i
cd `xcrun simctl getenv booted SIMULATOR_SHARED_RESOURCES_DIRECTORY`

Miscellaneous Bulk Actions

There are couple of dirty hack which might be useful as well in some cases when you don’t want so many simulators.

Erase all Simulators

We can erase all the simulators using the simple command

$ xcrun simctl erase all

Delete all the Simulators

The following script will delete all your simulators so beware of the impact and use when really needed.

$ xcrun simctl list | awk -F “[()]” ‘{ for (i=2; i<NF; i+=2) print $i }’ | grep ‘^[-A-Z0–9]*$’ | xargs -I uuid xcrun simctl delete uuid

Find Simulator by Name Regex

Sometimes we might need to find the simulator by name and perform action on that UUID. We can find that UUID using name and then erase/delete/boot simulator. Let’s erase simulator containing name “Shashi”

$ xcrun simctl list | grep -w “Shashi” | awk -F “[()]” ‘{ for (i=2; i<NF; i+=2) print $i }’ | grep ‘^[-A-Z0–9]*$’ | xargs -I uuid xcrun simctl erase uuid

Conclusion

Using simctl utility we can programatically interact with iOS simulators and script the setup for test execution on CI servers. What’s your experience with ‘simctl’, comment below.

Note: This artile has originally published on personal blog a.k.a XCBlog.Checkout my XCblog site for more interesting things about iOS DevOps, Continuous Integration/Delivery here