Saturday, November 03, 2007

Ruby Cocoa

RubyCocoa and the Scripting Bridge are two software development technologies bundled with Leopard. The app presented here demonstrate how to create a native Mac interface written in Ruby that communicates with iTunes via Applescript. It does nothing more than display the iTunes version number.
  1. Create a "Ruby-Cocoa Application" from the "New Project" dialog in XCode
  2. Add a "Ruby NSObject subclass" to the project called "ITunesController"
  3. Add an ib_outlet for a text field and an ib_action called "show_version" to the ITunesController ruby class.
  4. Generate an Objective-C header file that scripting bridge can use to communicate with iTunes. Use the two terminal command, sdef and sdp, within your project folder like this: "sdef /Applications/iTunes.app | sdp -fh --basename iTunes"
  5. Add the header file to your project.
  6. Add "ScriptingBridge.framework" to your project.
  7. Open "MainMenu.nib" in Interface Builder and add a button and a label to the Window. Also instantiate an NSObject subclass.
  8. Set the NSObject's class to "ITunesController". (You may need to select the "Read Class Files..." menu item to get ITunesController to show up as a valid option)
  9. Wire the button to your controller's "show_version" method and wire the controller's text_field outlet to the label.

Here's what my project looks like:


Here's what my Ruby "ITunesController" class looks like:

require 'osx/cocoa'

include OSX
class ITunesController < NSObject
ib_outlet :text_field
def show_version(sender)
iTunes = SBApplication.applicationWithBundleIdentifier:'com.apple.iTunes'
@text_field.setStringValue("iTunes version: #{iTunes.version}")
end
ib_action :show_version
end

Here's what the app looks like:


Now you should be able to run the project and get the iTunes version number displayed in your own application. Yeah, the end result is kind of lame but the journey was pretty cool. The interesting bits for me were:
  1. My Ruby class extends Cocoa's NSObject class.
  2. The class methods ib_outlet and ib_action are parts of the Ruby DSL for doing Cocoa development with Ruby.
  3. The RubyCocoa framework makes it really simple to swap out Objective-C for Ruby when doing Cocoa development.
  4. Everything else is the same. I still use XCode for my controllers and model and still use Interface Builder to graphically build my GUI and bind it to my code. The only difference is that I get to use Ruby and all of its beauty to get the job done.
  5. The downside is that I don't get anything too useful in the way of code completion while in XCode. Still might be worth it if you really dig Ruby.

3 comments:

Anonymous said...

Nice tutorial but I'd have preferred a more step-by-step like approach with lots of screenshots/code listings and/or a screencast.

Thanks for the tutorial,

Lucas

Pinux said...

Steps 4 and 5 are not necessary. There is no need to generate the header file and add it to the project because you access the framework from Ruby.

Nice tutorial though :-)

sundog said...

Thanks for the clarification. I should have realized that myself... :-)