In my opinion, Objective-C's big strength is the awesome Cocoa libraries. So as a Java programmer I was pleasantly surprised to discover the Rococoa project. Rococoa allows any Java program on Mac OS X to (sort of) easily access any Cocoa library.
If you want to use Rococoa I recommend learning how to code in Objective-C first. That will make it easier to understand what's going on and why you need to do things like creating an auto-release memory pool.
The hardest part of Rococoa's learning curve was getting a small but useful program working. Once I achieved that the other parts fell into place. So to help others, here is a working example, in two classes. The first class, NSWorkspace is an access point to Cocoa's NSWorkspace class. The second class uses NSWorkspace to dump to the console a list of all applications currently running on your Mac.
You'll need to add the Rococoa libraries to your classpath.
package com.barbarysoftware.pokercopilot.jna;
import org.rococoa.NSClass;
import org.rococoa.NSObject;
import org.rococoa.Rococoa;
import org.rococoa.cocoa.foundation.NSArray;
public interface NSWorkspace extends NSObject {
public static final _Class CLASS = Rococoa.createClass("NSWorkspace", _Class.class);
public interface _Class extends NSClass {
// class (aka static) methods go here
NSWorkspace sharedWorkspace();
}
// instance methods go here
NSArray launchedApplications();
}
---
package com.barbarysoftware.pokercopilot.jna;
import org.rococoa.Foundation;
import org.rococoa.NSObject;
import org.rococoa.cocoa.foundation.NSArray;
import org.rococoa.cocoa.foundation.NSAutoreleasePool;
public class HelloRococoaWorld {
public static void main(String[] args) {
final NSAutoreleasePool pool = NSAutoreleasePool.new_();
try {
showRunningApplications();
} finally {
pool.drain();
}
}
private static void showRunningApplications() {
final NSWorkspace nsWorkspace = NSWorkspace.CLASS.sharedWorkspace();
final NSArray nsArray = nsWorkspace.launchedApplications();
final int size = nsArray.count();
for (int i = 0; i < size; i++) {
final NSObject nsObject = nsArray.objectAtIndex(i);
// dump object to console the Java way
System.out.println("nsObject = " + nsObject);
// dump object to console the Cocoa way
Foundation.nsLog("%@", nsObject.id());
}
}
}


7 comments:
Glad to see you are digging into Cocoa. Programming for the Mac without access to those libraries seems like trying to paint without brushes. Good luck!
Bring on the shower? (or, at least, bath?)
;-)
@KeithX,
You know what really feels restricting? Offerint Tiger support. There's lots of nifty Cocoa libraries that only work in Leopard and upwards. And even more than only work in Snow Leopard upwards.
Some things that I do with polling could be do with event notification if I dropped Tiger support.
@ Steve,
I commented on this issue in the OS breakdown entry above. Personally, I think it's time to start requiring Leopard. I just don't see how you can get to a solid foundation for PCoP without extensive use of Cocoa.
Great article thanks.
I am trying to use Rococoa to read phone numbers from the Mac Address Book application but am having trouble. For a start I'm not sure how I can get access to the sharedAddressBook function which is available to the cocoa ABAddressBook API.
Even just getting that far for me would be great.
Shouldn't you be calling pool.drain instead of pool.release? I'm pretty sure in this case release is a no-op and your going to be leaking.
@Steven,
You are absolutely right. I've changed the sample code to use drain instead of release.
Post a Comment