Right now in Xcode 6, there are plenty of simulators to choose from but did you know that you could create your own simulators and customize them for specific testing needs?
The simctl command line utility, which you find at /Applications/Xcode6-Beta.app/Contents/Developer/usr/bin/simctl, enables you to create new custom simulators built to your specifications.
You start by creating a device, setting its class and its firmware. You discover the list of installed device types and simulator runtimes by issuing the simctl list command.
== Device Types == iPhone 4s (com.apple.CoreSimulator.SimDeviceType.iPhone-4s) iPhone 5 (com.apple.CoreSimulator.SimDeviceType.iPhone-5) iPhone 5s (com.apple.CoreSimulator.SimDeviceType.iPhone-5s) iPad 2 (com.apple.CoreSimulator.SimDeviceType.iPad-2) iPad Retina (com.apple.CoreSimulator.SimDeviceType.iPad-Retina) iPad Air (com.apple.CoreSimulator.SimDeviceType.iPad-Air) Resizable iPhone (com.apple.CoreSimulator.SimDeviceType.Resizable-iPhone) Resizable iPad (com.apple.CoreSimulator.SimDeviceType.Resizable-iPad) == Runtimes == iOS 7.0 (7.0 - Unknown) (com.apple.CoreSimulator.SimRuntime.iOS-7-0) (not installed) iOS 7.1 (7.1 - 11D167) (com.apple.CoreSimulator.SimRuntime.iOS-7-1) iOS 8.0 (8.0 - 12A4297e) (com.apple.CoreSimulator.SimRuntime.iOS-8-0)
For example, I might want a 7.1 install on an iPhone 5 to test my Fidget software. You provide simctl with the reverse-domain specifiers for each. So with these constants, the command I issue to create this simulator is as follows:
simctl create Fidget71iPhone5 com.apple.CoreSimulator.SimDeviceType.iPhone-5 com.apple.CoreSimulator.SimRuntime.iOS-7-1
Once built, issue the list command again to retrieve the UUID for your new device. You supply this UUID with each command to control your simulated device.
... == Devices == -- iOS 7.0 -- -- iOS 7.1 -- iPhone 4s (07357684-4C14-49A1-BD57-8C435CE7611E) (Shutdown) Fidget71iPhone5 (D6E1DD7F-712D-4273-A083-F9C9A12AED38) (Shutdown) iPhone 5 (F3FE995D-4808-4153-8800-E4EBB94DCB95) (Shutdown) ...
Each simulator is stored in ~Library/Developer/CoreSimulator/Devices. Each device folder stores its contents in the data subfolder. This enables you to hop in and inspect files as you run, for example looking at preferences or examining files in the Documents folder.
Once installed, Xcode presents your custom simulator along side the other standards. You select the simulator in Xcode and run apps as normal. Simctl keeps a running list of device states, so as you test, your device is listed as (Booted). Otherwise it is (Shutdown).
You run the simulator by opening it from its default location.
open /Applications/Xcode6-Beta.app/Contents/Developer/Applications/iOS\ Simulator.app
Then,from the command line, you can issue commands. For example, you can have it open a URL:
simctl openurl D6E1DD7F-712D-4273-A083-F9C9A12AED38 https://ericasadun.com
or add a photo to the photo library on the device:
simctl addphoto D6E1DD7F-712D-4273-A083-F9C9A12AED38 ~/Desktop/test.png
or launch an application:
simctl launch D6E1DD7F-712D-4273-A083-F9C9A12AED38 com.sadun.SwiftWorld
The utility comes with a pretty good help system. Just issue simctl without any arguments (or with –help) for more details.
Found some other cool tricks? Please let me know.
Thanks, “A”
13 Comments
This is really great information. Thanks for the post. – Tod
cool, info 🙂
Xcode has a way to build custom simulators in a GUI, you don’t need to use the command-line. I’m pretty sure you access it from the bottom of the destination dropdown menu, though I’m not at my computer right now to check.
Yup, found that via http://twitter.com/mrh_is/status/480139528405909505 !
[…] iOS 8: Building custom simulators (Erica Sadun) – Nice tool! […]
[…] Right now in Xcode 6, there are plenty of simulators to choose from but did you know that you could create your own simulators and customize them for specific testing needs? The simctl command line… […]
[…] Erica Sadun shows us how to Build custom simulators […]
By modifying a bit the SDK iPhoneSimulator6.1.sdk from Xcode 5.1.1 and the iOS 7.0.simruntime to iOS 6.1.simruntime the devices are recognized. On launch I get the following error: “The runtime for the selected device failed verification.” If anyone has some time to look into that, it would be very nice to have iOS6 simulator available in Xcode 6..
This is excellent. Is their a way of getting simulation log using XPC?
Another way of launching the simulator is open -a “iOS Simulator” –args -CurrentDeviceUDID
D6E1DD7F-712D-4273-A083-F9C9A12AED38
This allows you to select the simulator you want to launch rather than the last launched.
I noticed that the help for simctl says “If you want to set environment variables in the resulting environment, set them in the calling environment with a SIMCTL_CHILD_ prefix.” I found out that if you do:
export SIMCTL_CHILD_WK_APP_LAUNCH_MODE=NOTIFICATION
before launching your WatchKit App will cause it to go into the “Notification” entry point.
You will need to also set:
export SIMCTL_CHILD_WK_NOTIF_CONTEXT=’your notification json content in plist format’
because otherwise you’ll get a screen on the simulator saying it was not able to find the category “null” 🙂
Does anyone know how to detect the ‘sim device type’ of the currently running simulator? Is it possible to dig out a string similar to the UIDevice ‘platform’ extension method that tells us the simulated device?
In case anyone is trying this out on Xcode 7, you can prefix simctl commands with xcrun. For example: “xcrun simctl list” to list devices