Current Version: 0.6

Check out the tutorial, resources     and examples that are available.

Creating an Objective-C bundle to use with MacRuby

By Matt Aimonetti

Objective-C has a lot of very interesting libraries and Free Open Source code that
you might want to use in your MacRuby/HotCocoa projects.

Creating a MacRuby compatible bundle

If you are using MacRuby with Xcode, adding Objective-C frameworks,
dynamic libraries and third party code is easy and you just need to add the code
you want to use and make it available in your build target.

You might wonder how to do that when using HotCocoa or pure Ruby.

If you want to use a Cocoa Framework, you just need to make sure it’s in your path and then require it.

The easiest way to add non framework code is to create a Dynamic Library compatible with MacRuby and simply require it.

Let’s see how to do that:

Xcode template

Start Xcode and choose the Cocoa Bundle template.

Choose a name for your project and add the Objective-C files you want to make bundle.

Build settings

Edit your build settings as follows:

Click on: Project > Edit Active Target “TheNameOfYourTarget”

Pick the appropriate architectures and choose GCC version 4.0 or more recent.

Change the executable from ‘dylib’ to ‘bundle’. An if you want to, change the ‘product name’.
(From the Ruby side, we will later on require the bundle using this product name)

Finally, enable the Objective-C Garbage Collector.

Your project should now be properly setup to build, but we need one more thing.

MacRuby compatibility

Because we want our bundle/dynamic library to behave like a C extension and just require it, we need to add a constructor.
Choose an implementation file (.m file) and add an empty function as follows:

// Added for MacRuby
void Init_twitter_engine(void) { }

In this case ‘twitter_engine’ is the name of our bundle/dylib. (The name was set as `product name` in our build settings)
Use Init_XXX where XXX is the name of your bundle. When requiring your bundle, Ruby will automatically call this method.
If it doesn’t exist, Ruby will throw an exception.

Requiring the bundle

Your bundle now behaves just like a Ruby C extension, require it and start using it directly:

[mattetti@matt-aimonettis-macbook lib (master)]$ macirb
>> require 'twitter_engine'
=> true
>> engine = MGTwitterEngine.alloc.initWithDelegate(self)
=> #<MGTwitterEngine:0x8007a0e40>

Pretty easy, isn’t it?