inicio mail me! sindicaci;ón

Converting RubyCocoa Projects to MacRuby

After trying out MacRuby, the port of which directly runs on Objective C, i decided to try and convert some of my existing RubyCocoa projects over in order to take advantage of the speed boost and the simplified interface.

While the process was relatively straightforward, i have decided to reproduce it here so anyone else in my predicament can get their applications up and running in RubyCocoa with the minimum of fuss.

Preamble

Firstly, open up the Project Info box by double clicking on your project in the tree.

Your project needs to use the 10.5 sdk, since that is the only version which MacRuby supports. If you are planning on targeting 10.4, then MacRuby is not for you.

In addition you need to make sure you enable the Garbage Collection for Objective C, otherwise the MacRuby framework won’t link. In case you have forgotten where this option is, go to the build tab, select “All Configurations” for the configuration, then look for “Objective-C Garbage Collection“.

I selected “Supported“, though you can use “Required” as well.

Spot the difference

While a MacRuby project is similar to a RubyCocoa one, there are a few differences. Obviously, they use different frameworks, the initialization in ruby is slightly different, and of course there are a few big differences in the interface.

1) main.m

RubyCocoa

#import <Cocoa/Cocoa.h>
#import <RubyCocoa/RBRuntime.h>

int main(int argc, const char *argv[])
{
    return RBApplicationMain("rb_main.rb", argc, argv);
}

MacRuby

#import <MacRuby/MacRuby.h>

int main(int argc, char *argv[])
{
    return macruby_main("rb_main.rb", argc, argv);
}

2) rb_main.rb

RubyCocoa

require 'osx/cocoa'

def rb_main_init
  path = OSX::NSBundle.mainBundle.resourcePath.fileSystemRepresentation
  rbfiles = Dir.entries(path).select {|x| /\.rb\z/ =~ x}
  rbfiles -= [ File.basename(__FILE__) ]
  rbfiles.each do |path|
    require( File.basename(path) )
  end
end

if $0 == __FILE__ then
  rb_main_init
  OSX.NSApplicationMain(0, nil)
end

MacRuby

framework 'Cocoa'

# Loading all the Ruby project files.
dir_path = NSBundle.mainBundle.resourcePath.fileSystemRepresentation
Dir.entries(dir_path).each do |path|
  if path != File.basename(__FILE__) and path[-3..-1] == '.rb'
    require(path)
  end
end

# Starting the Cocoa main loop.
NSApplicationMain(0, nil)

3) Framework link

RubyCocoa

Located in /System/Library/Frameworks/RubyCocoa.framework

MacRuby

Located in /Library/Frameworks/MacRuby.framework

4) Generally speaking

Ignore the OSX module, use framework instead of require for frameworks, and don’t use ib_outlet or ib_action.

RubyCocoa

require 'osx/cocoa'

class MyClass < OSX::NSObject
  ib_outlet :myOutlet
  ib_action :myAction do |sender|
  end
end

MacRuby

framework 'Cocoa'

class MyClass < NSObject
  attr_writer :myOutlet
  def myAction(sender)
  end
end

In addition, since MacRuby is based on Ruby 1.9 (as opposed to 1.8.x) it would be a good idea to check for incompatibilities in your code which arise from changes in Ruby 1.9.

Celebrate

With any luck, provided you have followed the above and managed to convert all of your RubyCocoa code over, your app should now run with MacRuby!

 

Trackbacks

(Trackback URL)

close Reblog this comment
blog comments powered by Disqus