MonoTouch 1.0 goes live.

by Miguel de Icaza

MonoTouch is a commercial product based on Mono and is made up of the following components:

  • MonoTouch.dll The C# binding to the iPhone native APIs (the foundation classes, Quartz, CoreAnimation, CoreLocation, MapKit, Addressbook, AudioToolbox, AVFoundation, StoreKit and OpenGL/OpenAL).
  • Command Line SDK to compile C# code and other CIL language code to run on the iPhone simulator or an iPhone/iPod Touch device.
  • Commercial license of Mono's runtime (to allow static linking of Mono's runtime engine with your code).
  • MonoDevelop Add-in that streamlines the iPhone development and integrates with Interface Builder to create GUI applications.

The MonoTouch API is documented on the Mono site. The MonoTouch API is a combination of the core of .NET 3.5 and the iPhone APIs.

We have created some tutorials on how to use MonoTouch and you can read the design documentation on the MonoTouch framework.

Some History

Almost a year ago when we released Mono 2.0 for OSX, I asked the readers of this blog to fill a survey to help us understand where we should take Mono.

Many developers asked us to provide Mono for the iPhone.

A year ago, it was possible to use Mono's static compiler to compile ECMA 1.0 CIL bytecode for the iPhone. This is the technology that powered Unity3D's engine for the iPhone.

Users of Unity3D have published more than 200 applications on the AppStore.

We debated internally what exactly Mono for the iPhone would be. We considered doing a Windows.Forms port, to bring Compact Framework apps to the iPhone, but that would have required a complete new backend for Windows.Forms and would have required also a "theme" engine to make it look like the iPhone. We discarded this idea early on.

We decided instead to go with a native binding the iPhone APIs. It would not be a cross platform API and it would tie developers to the iPhone platform, but it would also mean that applications would look and feel native, and developers would get closer to the iPhone.

Creating a binding for the Objective-C APIs with .NET in the past has relied extensively on dynamic code generation, and this feature is not available on the iPhone (the kernel prevents JIT compilation from taking place). As we started doing the work to bind the low-level C APIs, Geoff started prototyping a new Objective-C/C# bridge that was specifically designed to work within the iPhone requirements.

By the time we had sorted out the foundation and the Objective-C bridge we had gained some fresh experience from binding the C++ PhyreEngine to .NET and we decided to create a new binding generator to simplify our life (I will blog about this new approach to binding creation in another post).

At this point, we started investing into supporting not only the device, but support the simulator. This would prove to be incredibly useful for quickly testing the code, without having to wait a long time to compile and deploy on the device.

The Developer Experience

At this point, we had enough to create mix-mode GUI applications (they were mostly Objective-C apps hosting Mono) and the pipeline was horrible: it involved using some 3 compilers, having 3 Mono checkouts and applying individual patches to all trees.

We were aware of how easy Unity had made things for their users, they had set the bar pretty high in terms of usability for us. Unity had some advantages, they could "debug" without deploying the code to the device, something that we could not really do ourselves.

We were still far from this.

We introduced a command that would isolate all of the complexities of creating simulator and ARM executables, the mtouch command.

With the mtouch command and the bindings complete, we started trying out the API by porting the Apple iPhone samples from Objective-C to C#. And in the process finding two things: C# 3.0 constructor initializers are a thing of beauty:

UIControl SliderControl ()
{
	var slider = new UISlider (new RectangleF (174f, 12f, 120f, 7f)){
		BackgroundColor = UIColor.Clear,
		MinValue = 0f,
		MaxValue = 100f,
		Continuous = true,
		Value = 50f,
		Tag = kViewTag
	};
	slider.ValueChanged += delegate {
		Console.WriteLine ("New value {0}", slider.Value);
	};
	return slider;
}
	

And also that the samples ported were half the size of the equivalent Objective-C programs.

As we were doing this work to iron out the kinks in the API design, Michael got started on designing the MonoDevelop support for the iPhone. This included the regular bits that you would expect like templates, building, running and deploying, but most importantly the Interface Builder integration.

Interface Builder produces an XML file that describes your UI, and it is able to generate some header files for you, but in general developers that want to refer to components in the UI and implement their backing store have to repeat the same stuff over and over. For example, controlling the contents of a label on the screen requires the developer to declare the same variable three times: 2 in the header file, and one in the Objective-C file (if you are lucky).

We took a different approach. We made it so that MonoDevelop would automatically generate a code-behind partial C# class for each Interface Builder file. This meant that to users the entire process would be transparent.

They would define outlets or messages, and those would just become part of their class. Intellisense and code completion would become available to them without any extra coding.

Posted on 14 Sep 2009