I'm the kind of guy who thinks better tooling means better outcomes. But when good tooling isn't available, it's time to build it yourself. It's this attitude that lead to my work on CocoaDocs.org, and then to CocoaPods.org & its documentation.

We've been trying to apply this to testing, and in order to pull this off I've had to extend Xcode to show off the results of failing tests in a more visual way. To that end, I've extended Xcode to show the results of failing view tests in a more visual way by building Snapshots for Xcode. Let's go through the process of building an Xcode plugin so you can do this too. Screw stability.

Getting started

Lets start of with some Xcode inception. The nicest way to start working on Xcode plugins is to install Alcatraz the Xcode plugin package manager:

1
curl -fsSL https://raw.github.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

From Alcatraz you should have XcodeExplorer installed. This lets you dig through internal notifications and the Xcode view heriarchy for debugging. Then you'll want Delisa Mason's Xcode 5 Plugin template which also comes from Alcatraz. Now you can create a new project and pick "Xcode 5 Plugin". This will do a bunch of the boring work around getting set up on a project, though it misses one bit that to me is essential, setting the Scheme Target. Once setup go to the Scheme editor and make it open Xcode as the target.

Go set you target dangit

This means that when you do cmd + r on your project it will open a new instance of Xcode with your plugin installed, making the dev cycle for a plugin as simple as a normal OS X app. From here I can't tell you how to build your plugin. It's just normal development, however I can offer some general advice:

  • When you see a class you don't know, google it, chances are Luis Solano has you covered with Xcode-RuntimeHeaders.
  • Use id with fake class interfaces to get around having the headers for Xcode's classes.
  • Avoid 3rd party dependencies as much as possible as all plugin classes are in the same runtime.
  • A lot of work is done in notifications, so it's easy to hook in to state changes.
  • Swizzle as little as possible
  • Wrap code you're not 100% on with @try {} @catch {} once it's working to crash elegantly
  • Look at the source code of other plugins
  • Read the notes on the Xcode5 Plugin Template

Releasing

Next up you want to get it on Alcatraz, this is just a pull request to the alcatraz-packages repo, it's like the old days of CocoaPods! Then you have a plugin, and people will always be using the master HEAD version of your plugin, so be wary around putting unstable code on that branch.

It's easy to forget that if you build apps you have all the tools you need to improve your workflow, one improvement that saves you an hour today could save thousands of human-hours once it's out in the community.

Categories: cocoa, ios, objc, plugins, testing, xcode