Monday, February 23, 2009

Hello, Xcode!

This post is "the making of" for a tool I'm writing that does automated modifications to Xcode projects. If you want to use the tool, or see the code, go to (scroll down to the bottom for the instructions).

To the best of my knowledge, Xcode does not have a public API for interacting with its projects (asides from building with xcodebuild), and there is no tool out there filling this gap.

Xcode has a pretty good user interface, so it may seem that such a tool isn't worth the trouble. I beg to differ. Do you have unit tests? If so, you know they belong in a separate target... and once you have more than one target, you've seen Xcode's less-then-stellar UI for managing target membership. Wouldn't it be nice to have all the files ending in Test.m automatically placed in your unit test target?

Managing test case membership is not that difficult. But then came the iPhone. Xcode has no decent way of incorporating other people's code in a project. My standard for "decent" is being able to add someone's code quickly, and then change that code, as well as receive upstream updates.

Last but not least, the project format is rather readable. I think it was designed to be understood, and I assume Apple folks won't be unhappy to see programmatic access to their format.

My Goals
I hope that, one day, iPhone applications will be as easy to develop as Rails applications. This is what I would like to get done, eventually:
  • merge targets from an Xcode project to another project; then we could have libraries that are as easy to integrate into projects as Rails' plugins (done)
  • sync between Xcode file listing and on-disk files; this would allow me to move files around in sub-folders, and have Xcode reflect my actions automatically; also, I would be sure I didn't forget to delete files that I removed from my Xcode project; this is especially important for headers, which can impact a build even if they're not in the project
  • build an iPhone application with all the settings needed for submission to the iTunes store
I know I can't possibly figure out how people will want to interact with their Xcode projects. After all, Apple tried and didn't get it perfectly right. So I wanted to make my tool inviting to use and learn, so fellow developers can code up the functionality they need quickly, and hopefully contribute it back to the project, so everyone's life is easier.

I developed the tool in Ruby, because I know and like the language. I packaged it using Rubygems, which comes pre-installed on OSX Tiger and above, so the tool can be installed with one command (the download happens automatically). I hope the quick installation will lower the barrier to adoption, and get me users, some of which will become developers.

I wrote a setup for Ruby's interactive sell (irb) so people can easily explore the structure of Xcode projects, and even experiment with changes. The 22 lines of code paid for themselves many times over, as I used the interactive shell myself to figure out. In the end, people will try to improve the tool if the time it saves them exceeds the time it takes them to learn the tool plus the time it takes to code the change. I hope the interactive shell tilts the scale in my favor.

I tried to make my code look decent, so it doesn't turn away developers who want to try changing it. I pushed big parts in separate directories, because having less to read is always nice. I used a plug-in architecture (don't think it's a big deal, it's less than 40 lines of code) to make it easy for others to implement new commands, and make it easy for me to intergrate the changes.

I wrote tests while developing, so I can feel when my API sucks, and so I can have good examples for using the API. This is asides from the traditional use of tests to assue quality.

Call for Contributions
I wrote this code because I didn't want to do repetitive actions while working with Xcode. I hope I'm not alone.

My code is a good foundation for tweaking Xcode projects. But a good foundation is nothing without good features on top. This is where you come in. Fork the project on Github, do something, and send me your changes!

No comments:

Post a Comment