Friday March 14, 2014

✦ UI Screen Shooter - Now Simpler and More Robust Since Xcode 5.1

The UI Screen Shooter scripts have been updated for Xcode 5.1! I’m quite pleased with the results. The instruments command line tool now lets us specify the simulator device directly from the command line. I’ve cleaned up the scripts and they are much easier to follow. Kudos to Apple on this! And thanks to Christoph Koehler’s issue that brought all this to my attention.

If you’d like more details on what changed, read on.

The Old Way of Hacking Things

You no longer have to force Xcode to pick the iPhone architecture with the TARGETED_DEVICE_FAMILY configuration parameter. Previously, the instruments command line tool would not let you pick whether you wanted to run on the iPad or iPhone simulators. If an app was marked as universal, Instruments would always launch the app in the iPad simulator. The hack to get around that was to set the TARGETED_DEVICE_FAMILY to 1 which would force Xcode to build the app as iPhone only. Instruments would then oblige and only launch the iPhone simulator.

In order to get screenshots on both iPad and iPhone, you had to build twice with different TARGETED_DEVICE_FAMILY settings. It was a real pain, but it worked.

You also no longer have to muck with the simulator preference files to force the simulator to launch in a specific language. Previously, I hacked together a shell script that used PlistBuddy to alter the preference files, forcing the simulator to think only a specific language and locale was available. But thanks to a post by Ole Begemann on NSUserDefaults, I realized that I can force the simulator to pick a locale by just passing special command line parameters.

And that’s not all! You also no longer need to force the simulator to a specific device model with AppleScript! Previously (you can see a theme here), I used an AppleScript that launched the simulator and picked the proper device type from the Hardware menu. When Instruments next launched, it would use the previous simulator setting. Again, it worked but it was a horrible hack.

Update: Brad Grzesiak just pointed out to me that there’s no longer the need for my pty/tty hack in the unix_instruments wrapper since the Instruments command line tool no longer buffers it’s output when piped. We still need the wrapper script, though, because Instruments doesn’t return a non-zero status code on JavaScript failure, but hey, I’ll take every opportunity I can get to remove my workaround code.

The New, Glorious Way

All that changed in Xcode 5.1 because Instruments now supports specifying the simulator hardware type and iOS version all from the command line! To find out what options you currently have you on your machine, just type the following:

instruments -w help

And then you’ll see something like this:

iPhone Retina (3.5-inch) - Simulator - iOS 7.1
iPhone Retina (4-inch) - Simulator - iOS 7.1
iPhone Retina (4-inch 64-bit) - Simulator - iOS 7.1
iPad Retina - Simulator - iOS 7.1
iPad Retina (64-bit) - Simulator - iOS 7.1

Finally! It doesn’t matter what you put after the -w flag. You just need to pass something invalid and instruments gives you the valid options. Pass one of these strings in like so to use it:

instruments -w "iPad Retina - Simulator - iOS 7.1" ...

Note that you need the quotation marks because of the spaces in the full name of the simulator hardware type and version. Also, the -w flag must come at the start of the command line, before any other flags. Otherwise you get strange errors.

Check out the full screen shooter repository for more details. Use this as the basis to write your own screen shooting scripts. Enjoy!