Adventures in Mac World - Part 1

I needed to get myself a new laptop, and after much deliberation decided to treat myself to a Mac, for a variety of reasons, not the least of it being that i was curious about the Mac platform and wanted an option to test our products on Mac OS X – including Chrome and our Mono libraries, but also the new FPC support we have been shipping in ‘Vinci’, as well. At the very worst, i figured, the MacBook Pro would make a great Vista machine if i found i really couldn’t stand Mac OS.

As it turns out, i’m very happy with Mac OS X so far, and liking it quite a bit. And the new VMware Fusion (conveniently released the day before my MBP arrived) makes it easy to fall back to Windows apps – such as Visual Studio or our internal BugClient – where needed

One of the first things i tried, naturally, was to install Mono and Chrome and test the command line compiler and apps. But running the FileFind sample got boring after a few minutes, and i wanted to try some more exciting things, such as creating a proper Mac OS GUI app. The first obvious choice was, of course, WinForms, which i am familiar with and is by now well supported by Mono, as well. After figuring out i had to manually install X11 off the Mac OS CDs, WinForms apps ran well, however, they did not really feel “native Mac” – no icon in the dock, no proper top menu, etc.

It turns out, to get proper Mac OS X feel from a Mono app, the only real choice is to use Cocoa#, the managed wrapper for Apple’s standard UI framework. Documentation on Cocoa# is next to non-existent (and the bit i did find was hopelessly out of date and wrong), after with a bit of experimenting, it all worked surprisingly well.

Setup

To get started, let’s look at the tools and software that’s required. I’m running Mac OS X 10.4 (Tiger) and also installed Xcode Tools (which might or might not be pre-installed on your Mac; if not, you can install it using the “Optional Components” setup found on the Mac OS X install CDs). Lastly, on the Mac side, you will need Mono 1.2.4 for Mac OS (available here).

To make development easier, i also installed Chrome with Visual Studio inside VMware Fusion, and installed Mono 1.2.4 for Windows (also available here), so i can directly link against Mono from inside Visual Studio.

Mono for Windows does not deploy the Cocoa# dll (which soft of makes sense, since it won’t work under Windows), but i manually copied it over so i can use it from Visual Studio. You can find cocoa-sharp.dll in

/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/cocoa-sharp

on your Mac and simply copy it over to

C:\Program Files]Mono-1.2.4\lib\mono\cocoa-sharp

Note that the the cocoa-sharp.dll found i the above folder most likely is a symbolic link, which VMware Fusion apparently cannot directly copy to the VM directly via drag and drop; you might need to follow the link back to the real file.

Getting Started

If you’re running Chrome ‘Joyride’ 2.0.3 or later, you will find a new ready-made template for Cocoa# in the New Projects dialog (in the MonoChrome subfolder). Use this template to create a new project.

![](http://blogs.remobjects.com/blogs/media/Templates.png)
Working with Cocoa# will require a lot of switching back between Mac OS and the Windows VM, so rather then copying the project back and forth frequently, i suggest creating it in the shared folder that VMware Fusion created for you, sharing your Mac home directory. In my case, this was mapped to drive Z:\ under Windows, and mapped to my ~mh folder, Mac Side.

First thing after creating the project, you will notice a few unfamiliar files – a .ICNS file containing the application icon, and a .NIB folder containing the Cocoa interface definition that describes the UI of your application. Visual Studio will not be able to edit the files in this folder (except in text or binary mode, which is quite useless), but fortunately Interface Builder, provided as part of the Xcode Tools, can.

![](http://blogs.remobjects.com/blogs/media/SolutionExplorer.png)
So, switch back to Mac OS, locate your project folder in Finder and double-click the Interface.nib (you will notice that Finder treats the entire folder as a single file, a so called “package”, even though in Visual Studio it appears as a folder) to open Interface Builder:
![](http://blogs.remobjects.com/blogs/media/InterfaceBuilder.png)
As you see, Interface Builder opens with four windows:
  • A design surface for your application’s main form
  • A designer for the application menu
  • The Toolbox
  • The project window containing all elements defined for your UI.

Going into the details of designing Cocoa GUIs would go beyond the scope of this text, so lets simply drop a text control on the form and double-click it to change its caption to “Hello World!”, and also double-click the “NewApplication” in the main menu to change it, too, to “Hello World”, the name of our project.

Being happy with the UI, do File|Save (⌘S) and switch back to Visual Studio. There’s not really anything we need to do in code for our simple Hello World, so just do a Build|Build Solution to compile the project.

We’re almost ready to run now; as a last step, we need to package our project as a Mac .APP application, so we can run it. To do this, open a Terminal window, and navigate to your project’s bin/Debug folder (ie ~mh/Hello World/bin/Debug in my case), and run the following command:

macpack -m:2 -n:HelloWorld -a:HelloWorld.exe -r:Interface.nib -i:App.icns

As a result, a HelloWorld.app (this again is a package folder that Finder will treat as a single file) will be generated, which will behave like any other Mac app – you can deploy it to the Applications folder, drag it to the Dock and, of course, double-click it in Finder to launch it:

![](http://blogs.remobjects.com/blogs/media/Dock.png)