This tutorial will guide you through the process of making a Cocoa application that leverage the power of the Monobjc bridge. The project is part of the sample applications and can be found in the distribution.

Before following this tutorial, make sure that you have correctly installed both the Monobjc bridge and the MonoDevelop addins.

The tutorial is divided into the following steps:

  • Creating the project
  • Writing some .NET code
  • Building
  • Running
  • Writing more .NET code
  • Debugging
  • Packaging

Creating the project

Launch MonoDevelop and select File => New => Solution.... Open the C#/Monobjc folder and select Cocoa Application.

Name the application as you want (MyApplication for example) and click the OK button. The new solution as well as the application project will be created.

The project contains a basic Cocoa application with the following files:

  • en.lproj/MainMenu.xib: this is the main Interface Builder file that describe the user interface. It contains a window instance.
  • AppDelegate.cs: this is the application delegate. Every Cocoa application is controller by an application object (a NSApplication instance); this instance can forward events to its delegate. It is useful to know when the application is ready or if the application is about to terminate.
  • AppDelegate.designer.cs: this is the designer part of the application delegate. This code is generated by extracting information contained in the main Interface Builder file.
  • Info.plist: this is the application descriptor that contains its name, version, identifier, supported version, etc.
  • Program.cs: this is the main entry point of the application. The main method is responsible for loading the frameworks and to bootstrap the application.

Writing some .NET code

We want to extend the basic application with some logic. We want to know when the application has finish its loading and is ready, and we also want to indicate that when the last window is closed to quit the application. This can be done by implementing a formal protocol.

Open the AppDelegate.cs source file. Do a right-click on the AppDelegate declaration and select Refactor => Implement Protocol. You see a window that list a series of informal protocol. Search for NSApplicationDelegate and select the row. Below, you see a list of the methods for this protocol. Check the ApplicationDidFinishLaunching and ApplicationShouldTerminateAfterWindowClosed. When done, click on the button. An insertion point appears in the source code. Select the place where you want the method to be inserted and press the Return key. The stub for the two methods have been generated.

We now need to implement these two methods so they are useful. In ApplicationDidFinishLaunching, we put a simple Console.WriteLine statement. In ApplicationShouldTerminateAfterWindowClosed, we simply return true to indicate that the application must terminate when the last opened window is closed.

Building

For the building, just click on the Build button or select the Build menu. The application is compiled and the Cocoa bundle is created.

Running

When the build is over, you can run the application. Select the project and click on the Run button or select the Run menu.

The application is now running. You can see a message in the MonoDevelop's output console, indicating that the application delegate has been called. If you close the window, the application terminates.

Writing more .NET code

Now, we want the application to have a button, that when clicked displays the frame of the window into a label.

The following section uses techniques found in the page Building UI with Xcode.

  • Double-click on the en.lproj/MainMenu.xib.
  • It opens the Xcode application.
  • Open the toolbox.
  • Select the NSButton widget and drag it on the main window.
  • Put it where you want.
  • Do the same with a NSTextfield widget.

In order to reference the text field widget, we add an outlet to the application delegate class definition.

  • In Xcode, click on the Wizard button to get a split view. On the top, the xib file is displayed, and on the bottom select the header file where you want to add the outlet.
  • Press and maintain the CTRL key while clicking and dragging the UI control to the header file. Xcode will let you choose if you want to create an outlet or an action.
  • Give a name to the outlet. The outlet is now defined in the header file and bound the UI control.
  • Click in the UI zone and save the xib file.

The connection between the AppDelegate and the label is made.

We want the button to trigger an action on the AppDelegate.

  • Press and maintain the CTRL key while clicking and dragging the button to the header file. Xcode will let you choose if you want to create an outlet or an action.
  • Give a name to the action, "showFrame:". The action is now defined in the header file and bound the UI control.
  • Click in the UI zone and save the xib file.

The connection between the button and the AppDelegate is made.

Now that we have modified the user-interface, we can save the Interface Builder file. When the file is saved, MonoDevelop detects it and a new designer code is generated. Open the AppDelegate.designer.cs file. You can see that the outlet and the action are now ready to be used.

Open the AppDelegate source file. Type the partial keyword. A completion window appears and let you select the ShowFrame method. This partial method is called when the button is pressed. Put a simple statement in it.

Debugging

Put some breakpoints in the code. For example, put it one in ApplicationDidFinishLaunching and another one in the ShowFrame method.

Select the project and click on the Debug button or select the Debug menu. The application will launch in debug mode and stops on the first breakpoint. You can inspect the variables or locals.

Press the `Debug button to continue the execution.

Now, press the Debug button. The other breakpoint is now triggered. You can advance step by step and inspect the variables and locals.

Press the Debug button to continue the execution.