iOS Simulator & xcrun simctl - Part 2

03 Apr 2016

The iOS Simulator has a wide range of settings, which can be changed via the menu. In a continuous integration system it’s essential to be able to change these settings within an automated script. The simctl gem has some features that help you automating these setting changes in the iOS Simulator.

iOS Simulator settings

Window menu

It is possible to change the window size of the Simulator.app:

iOS Simulator window menu

This can also be achieved by passing some options to the launch! method of the simctl gem:

require 'simctl'

device = SimCtl.device(name: 'iPhone 5')
device.launch!(0.75) # 75%

Debug menu

In the Debug menu there are some settings that are written to some preferences file in the plist format. The file can be found here: ~/Library/Preferences/com.apple.iphonesimulator.plist

This path might change in later versions of Xcode, the path displayed here is for version 7.3 of Xcode.

iOS Simulator debug menu

To see how these settings are named in the plist, just change something in the menu and see afterwards what has changed in the file. Most of these settings can be passed as launch arguments to the Simulator.app.

The simctl gem does support this too:

require 'simctl'

device = SimCtl.device(name: 'iPhone 5')
device.launch!(0.75, {
  '-OptimizeRenderingForWindowScale' => 'YES',
  '-GraphicsQualityOverride' => '10',
})

After launching the Simulator.app like this, the settings in the Debug menu have changed:

iOS Simulator debug menu

Settings app

iOS Simulator Settings app

Other behaviour can be modified inside the Simulator via the iOS app called Settings, just like on a real iPhone or iPad. These settings are not stored in com.apple.iphonesimulator.plist, instead they are stored in another file, which is different for each device. The path to this file depends on the udid of the device. There’s an easy way to find this path:

require 'simctl'

device = SimCtl.device(name: 'iPhone 5')
puts device.path.preferences_plist
/Users/plu/Library/Developer/CoreSimulator/Devices/AA31DD5D-E69F-45C8-90C7-E50CD98B06A9/data/Library/Preferences/com.apple.Preferences.plist

If you need to change some of these settings as part of your CI setup, the simctl gem can be helpful. First you need to figure out how these settings are called in the plist file. Just change them in the Simulator’s Settings app and see what has changed in the file. To disable all the keyboard related settings you would do:

require 'simctl'

device = SimCtl.device(name: 'iPhone 5')
device.settings.edit_plist(device.path.preferences_plist) do |plist|
  %w(
    KeyboardAllowPaddle
    KeyboardAssistant
    KeyboardAutocapitalization
    KeyboardAutocorrection
    KeyboardCapsLock
    KeyboardCheckSpelling
    KeyboardPeriodShortcut
    KeyboardPrediction
    KeyboardShowPredictionBar
  ).each do |key|
    plist[key] = false
  end
end
device.launch!

Now the keyboard section in the Settings app looks like this:

iOS Simulator Settings app

These keyboard settings can interfere when you’re using some sort of UI Testing (e.g. KIF) that involves real typing on the keyboard. Autocorrection will not be your friend in that case. Because this might be a common scenario, the simctl gem has a shorter way to disable all these keyboard settings:

require 'simctl'

device = SimCtl.device(name: 'iPhone 5')
device.settings.disable_keyboard_helpers!
device.launch!

That’s all for today, let’s see if I can make it for another part.

You can read more about this topic in part 1.