“Everything that can be automated must be automated.”
I spent almost 20 years in Manufacturing following that principle, because it works on so many levels. Old habits die hard, so even after I started doing more software / less hardware I still found myself following that deeply ingrained directive. And it’s just as valid in software as it was in hardware.
I’m not talking about Robot’s writing your ‘for loops’ (yet), but a great deal of our daily grind programming customized code, doesn’t involve coding at all. Programming has evolved: We now spend as much time outside .h and .m files as in them.
Interface Builder, Organizer, Git, Terminal, Pivotal, Photoshop and a dozen other tools in a toolbox that has become the new stack.
A lot of that has become extraordinarily repetitive, a clear sign it needs to be automated.
Lets take graphics for example…
A friend was watching me add about 50 new png images to a project, a common and completely normal activity when you’re making an app.
I dragged that folder to the desktop … and went to get a coffee.
All the image files were renamed to lowercase – hyphens changed to underscores – errors fixed – files got moved into the correct project ‘Resources’ directory – non-Retina versions generated if missing – imported the files into correct directory in XCode and the project was rebuilt, cleaned and compiled.
By the time I got back everything was done and he was pointing a finger at me: “You’re going to tell me how you did that.”
The whole process took just 30 seconds actually, getting the coffee took much longer. It would take a human being a full minute to process each one manually, the better part of an hour very likely.
The answer is at the bottom of this post if you are impatient, go ahead and jump.
Setting it up was quick and easy. I used OS X’s built-in Automator program and some Applescript to make and attach a multi-stage “script” to my project folder.
Zero code was written in making it.
Automator comes standard with OS X. Most people have heard of it. Few have used it and fewer still truly understand the incredible things it is capable of. The integration with OS X Applications, and XCode in particular, means you can automate pretty much anything.
Lets look specifically at some examples of the App creation process we can automate, three “hooks” XCode provides where you can tie-in your own custom automation:
1. Run Scripts
Under Project > Build Phases you will find a button labeled Add Build Phase that hides a second function, Add a Build Script. This allows you to execute a Bash script prior to your project running. This hidden feature has been invaluable for scripts that verify your projects has what it needs to run.
For example, I write scripts that check that required cocoa pod and sub modules are installed and core data databases don’t need rebuilding. They spit out helpful messages to the user letting them know exactly what the problem is and what to do about it. When you are working on someone else’s code this is a life saver, so pay it forward!
The default Xcode behaviours are actually pretty good. But at the very bottom, there is one more hidden little checkbox that has nothing to do with ‘Behaviours’ per se, it’s a checkbox labeled Run Script.
After creating a new “Behaviour” by clicking another tiny little box with a “+” in it and checking that box, you can point it at any Bash .sh script you’ve got. To trigger it, you can assign a hot key to run that behviour, which runs the script.
Being able to run any Bash script with a hotkey can be super-powerful, really only limited by your UNIX scripting skill. Git commands, deploying builds, grep’ing files … just to name a few.
For example, something super boring that I use a dozen times a day when I’m ready to make a git commit:
tell application "Terminal"
do script "cd ~/Workspace/MyProject" in window 1
do script "git status" in window 1
This opens a terminal window and does a simple git status report on my project. It’s trivial, but it saves me two clicks, a drag and typing 40 characters. One tiny script saves me 11 seconds, not much, but that’s two minutes every day and 45 minutes each month … now that tiny script is getting significant.
And we’re just getting started.
This particular scipt is really just a wrapper around something mich easier to understand than Unix scripting, osascript is the bash shell command to run OS X Applescript.
Applescript is Apple’s scripting language, and it does some terribly clever tricks:
- It’s English-like syntax is user friendly and easy to read and write.
- You can interact with ANY OS X application.
- You can “write” Applescript by simply recording actions using Automator.
3. XCode Plug-ins
The last hook is something that’s going to get a lot more attention with XCode 5.
Plug-ins. While they are a lot more challenging (and time consuming) to make, they can directly connect hot keys, your code, Applescript, Automator, Bash files and the World Wide Web.
You could remap CTRL-P to order a pizza right to your front door in five minutes, plus 30 for delivery.
Instead however, lets take a look at my favorite Plug-in right now, BBUncrustify.
This brilliant piece of work allows you to run a customized Uncrustify script against some code you just typed, or entire project. Uncrustify reformats the ugliest code you’ve got to a standard you simply supply with a ‘cfg’ file. I made this cfg for ObjectiveC.
It only affects whitespace, but it will ungarble even the most spaghetti-like code into a professional, readable, standardized format.
That’s very powerful for a number of reasons: It makes working with code faster, easier to read and interpret, errors become more noticeable because they stand out visually, meaning it will also improve your code quality.
Best of all, being on a hotkey, you can stop spending your time formatting code when you write it in the first place. Write your code quick and dirty, let the plug-in do all the work to format it’s visual appearance.
Faster development, better quality, error checking, resource management … wow, what else can we automate??
A better question might be, what can’t we Automate.