DRb and NSDistributedNotificationCenter in RubyCocoa

I’m writing an OS X GUI test runner for Ruby. It’s coming along nicely, and I’ll have something to show fairly soon. In the meantime, I’m going to share some things I discovered in the process of writing it.

First, DRb (Distributed Ruby) doesn’t play well with Cocoa objects, due to incompatibilities between Ruby’s threading and Cocoa’s calling model. Sometimes it works; mostly, it results in segmentation faults.

Instead of DRb, I decided to use NSDistributedNotificationCenter, OS X’s own distributed notification system. I couldn’t find many examples of usage on the internet. There were zero server examples in Ruby, and one in Python. After a bit of trial and error, I got it working; hopefully Google and this page will save someone else the trouble.

Here’s some sample server code:

require 'osx/cocoa'

include OSX

class Server < NSObject
  def foo(notification)
    p notification_to_hash(notification)
  end
  
  def notification_to_hash(notification)
    nsd = notification.userInfo
    return nsd.allKeys.to_a.inject({}){ |hash, oc_key| 
      hash[oc_key.to_s] = nsd.objectForKey(oc_key).to_s
      hash
    }
  end
end

server = Server.alloc.init

center = NSDistributedNotificationCenter.defaultCenter
center.addObserver_selector_name_object(
  server,
  "foo:", 
  "My Notification",
  "com.example.MyApp"
)

NSRunLoop.currentRunLoop.run

And the client:

require 'osx/cocoa'

include OSX

center = NSDistributedNotificationCenter.defaultCenter
center.postNotificationName_object_userInfo_deliverImmediately(
  "My Notification",
  "com.example.MyApp",
  {"foo" => "bar", "baz" => 3},
  true
)

It’s generally quite simple, but it’s important that the server object be an instance of an NSObject (or one of its descendants). Plain Ruby objects cause bus errors.

Comments

Skip to the comment form

  1. Matthew Egan

    Wrote at 2006-06-27 01:06 UTC using Safari 417.9.3 on Mac OS X:

    I found this useful ….

    http://www.hmug.org/man/3/notify.php

    A notification producer.

    #include
    ...

    notify_post(“com.eg.random.event”);

    Users of this API are highly encouraged to follow the reverse-ICANN domain name convention used for Java package names and for System Preferences on Mac OS X.
    For example, “com.mydomain.example.event”.

Leave a comment

Please read the comment guidelines before posting. Comments are Gravatar-enabled. Your email address will not be published.

To prove that you’re human, type human in the Bot check field.

Trying to post some program output or a long code sample? Please use a paste service and link to it instead.