Miguel's OSX and iOS blog Miguel's OSX and iOS blog http://tirania.org/monomac//index.html Miguel de Icaza miguel@gnome.org Mon, 11 Mar 2013 11:33:00 -0500 http://backend.userland.com/rss lb# Contribute Your Storyboard Files for Humanity <p>Ok, ok, not quite for humanity. <p>We are trying to improve our support for Xamarin Studio integration with Storyboard files, and we would like to collect a bunch of different samples. <p>If you can share your <code>.storyboard</code> file with us, please email alan at xamarin.com just the .storyboard file http://tirania.org/monomac/archive/2013/Mar-11.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2013/Mar-11.html Mon, 11 Mar 2013 15:33:00 -0500 Using Instruments to profile Mac apps built with Mono <p>On most platforms, Mono generates code dynamically as your software runs. The Instruments profiler does not have the ability to map a memory address of the generated code back to the name of your function being executed. This makes it pretty hard to find the hot spots in your code, or the bit of code responsible for a memory leak. <p>To solve this problem, you can use Mono's ahead of time compiler to precompile your code to native code. This will improve startup performance and also give you symbols in stack traces in Instruments. <p>To do this, run mono with the --aot flag over all of the assemblies that your project uses. This is the script that I ran to precompile all of my system libraries: <pre> cd /mono/lib/mono for i in `find gac -name '*dll'` */mscorlib.dll; do mono --aot $i done </pre> <p>This precompiles all of the assemblies from the Global Assembly Cache (GAC) and also takes care of all of my mscorlib libraries (these are not loaded from the GAC). <p>Then you need to add your own software: <pre> $ mono --aot bin/Debug/*.{exe,dll} </pre> <p>Now, when you use Instruments, you will get nice symbolic stack traces for your process. <p>Thanks to Alan McGovern for showing me this trick. http://tirania.org/monomac/archive/2013/Jan-03.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2013/Jan-03.html Thu, 03 Jan 2013 18:50:00 -0500 Translating Objective-C adopts-protocol idioms to C# <p>Sometimes when looking at Objective-C samples, you might run into code that adopts protocols and you wonder how to port that code to C#. It typically looks like this: <pre> @interface TransparentOverlay : UIView &lt;UITableViewDelegate, UITableViewDataSource&gt; { } </pre> <p>The above means that the "TransparentOverlay" object subclasses UIView and adopts two protocols: UITableViewDataSource and UITableViewDelegate. <p>The above does not really work with MonoMac or MonoTouch, since we mapped protocols into classes. In both bindings UITableViewDelegate and UITableViewDataSource are <a href="http://docs.xamarin.com/ios/Guides/Advanced_Topics/API_Design#Models">"model" classes</a>. <p>The real meat of this is that somewhere in the implementation of TransparentOverlay, a UITableView will be created, and both its delegate and its data source will be configured to point to the TransparentOverlay source, something like this: <pre> - (void) setup { myTableView = [[UITableView alloc] initWithFrame:...]; myTableView.delegate = self; myTableView.dataSource = self; } </pre> <p>The adopted protocol allows you to perform the assignemnt there. <p>The equivalent code in C# needs to create a helper class that derives from the model. This is the full implementation: <pre> class TransparentOverlay : UIView { UITableView tableview; class MySources : UITableViewSource { TrasparentOverlay container; public MySources (TrasparentOverlay container) { this.container = container; } override void MethodOne () { container.DoSomething (); } } void Setup () { tableview = new UITableView (....); var mySource = new MySources (this); tableView.Delegate = mySource; tableView.DataSource = mySource; } }</pre> <p>Note that the UITableViewSource is an aggregated version of UITableViewDataSource and UITableViewDelegate, it is just a convenience Model for a very common idiom. <p>As you can see, instead of using "self" to point to the "TransparentOverlay" instance, you need to make it point to the mySource instance. <p>The methods in MySource can get access to the content of their container by using the "container" property as illustrated by the MethodOne method. http://tirania.org/monomac/archive/2012/Nov-27.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Nov-27.html Tue, 27 Nov 2012 16:00:00 -0500 CoreMIDI in MonoTouch/MonoMac <p><img src="http://tirania.org/images/mt-coremidi.png" width=240 align="right">This new release of MonoTouch (and MonoMac) come with our new CoreMidi bindings. In the same spirit of the work that we did for AudioToolbox and other frameworks, we created a C# bindings that follows the .NET framework guidelines for the API. <p>When I started these bindings, I knew close to nothing about MIDI. It is a framework that is not exactly <a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">well documented</a> for people new to MIDI, but posts like <a href="http://goodliffe.blogspot.com/2010/10/using-coremidi-in-ios-example.html">this</a> helped me get these bindings sorted out. <p>MonoTouch/MonoMac binding resembles in many ways the object-oriented bindings that developers have created to make CoreMIDI <a href="https://github.com/petegoodliffe/PGMidi">easier to digest</a>. At its core, it is still an object oriented framework, that happens to be exposed with a fairly hostile C interface. <p>Our interface surfaces the underlying object oriented system with a strongly typed C# interface. Unlike the C interface that exposes a general property querying system that applies to all midi objects (MidiDevice, MidiEndpoint, MidiEntity, MidiPort), the binding ensures that only the available properties for each main class are exposed. This is a convenient way of avoiding a trip to the docs and to google to find samples. <center> <a href="http://iosapi.xamarin.com/?link=N%3aMonoTouch.CoreMidi"> <img src="http://iosapi.xamarin.com/monodoc.ashx?link=source-id:1:midi-components.png" width="400"> </a> </center> <p>To save developers some pain, as I developed the binding, I documented my findings in the <a href="http://iosapi.xamarin.com/?link=N%3aMonoTouch.CoreMidi">MonoTouch.CoreMIDI</a> documentation and added various samples to our API docs: <p>Our <a href="https://github.com/xamarin/monotouch-samples/tree/master/CoreMidiSample">CoreMidiSample</a> is a tiny program that replicates most of the funcionality of the MIDI sample apps, and is an easy starting point for people that want to get started with MIDI on iOS. <p>Interesting CoreMidi events are turned into C# events, so you can listen to changes like this: <pre class="code-csharp"> client = new MidiClient ("CoreMidiSample MIDI CLient"); client.ObjectAdded += delegate(object sender, ObjectAddedOrRemovedEventArgs e) { Console.WriteLine ("Object {0} added to {1}", e.Child, e.Parent); }; client.ObjectRemoved += delegate(object sender, ObjectAddedOrRemovedEventArgs e) { Console.WriteLine ("Object {0} removed to {1}", e.Child, e.Parent); }; client.PropertyChanged += delegate(object sender, ObjectPropertyChangedEventArgs e) { Console.WriteLine ("Property {0} changed on {1}", e.PropertyName, e.MidiObject); }; client.ThruConnectionsChanged += delegate { Console.WriteLine ("Thru connections changed"); }; client.SerialPortOwnerChanged += delegate { Console.WriteLine ("Serial port changed"); }; // // Create your input and output ports // outputPort = client.CreateOutputPort ("CoreMidiSample Output Port"); inputPort = client.CreateInputPort ("CoreMidiSample Input Port"); // Print out packets when we receive them inputPort.MessageReceived += delegate(object sender, MidiPacketsEventArgs e) { Console.WriteLine ("Got {0} packets", e.Packets.Length); }; </pre> http://tirania.org/monomac/archive/2012/Sep-11.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Sep-11.html Tue, 11 Sep 2012 22:07:00 -0500 MonoTouch and UIKit Thread Safety <p>No major UI toolkit is thread safe. <p>This means that these toolkits are not designed to have their exposed methods be invoked by multiple threads at the same time from multiple threads. The main reason is that building thread safe toolkits is both a very hard problem and can have very complicated semantics for the consumer of the toolkit. <p>Developers typically use multiple threads in UI applications to offload tasks that would otherwise block the user interface. The work is offloaded to a background thread that can take as long as it wants or can perform various blocking operations like disk or network operations without affecting the interactive nature of the application. <center> <img src="http://tirania.org/s/98851931.png"> </center> <p>When the background code completes its work, it queues an operation to be executed on the main thread to perform any required UI updates. <p>In MonoTouch and MonoMac the queuing of the operation from the background thread to the main thread is done using the <a href="http://iosapi.xamarin.com/?link=M%3aMonoTouch.Foundation.NSObject.InvokeOnMainThread(MonoTouch.Foundation.NSAction)">InvokeOnMainThread</a> or <a href="http://iosapi.xamarin.com/?link=M%3aMonoTouch.Foundation.NSObject.BeginInvokeOnMainThread(MonoTouch.Foundation.NSAction)">BeginInvokeOnMainThread</a> methods. <p>The rule among toolkits is: do not access any toolkit APIs from the background thread since there is nothing in the toolkit API to defend against internal state corruption caused by multiple threads updating internals at the same time. Failure to follow this rule can lead to subtle bugs or crashes. The offending code is typically very hard to track down since the problem is timing sensitive and the corruption can vary from run to run. <h2>Helping Developers Write Better Code</h2> <p>In theory, it is very easy to avoid making UIKit calls from a background thread, it only takes discipline. But some developers are not even aware that they are making UIKit calls from a background thread because their code so far has not crashed (they have been mostly luck). Another problem is that software is continuously evolving, and it is possible for developers to accidentally use UIKit APIs from a background thread during a refactoring pass, or when new features are introduced by a team members that was not aware of the clean split. <p>With MonoTouch 5.4 we have introduced a feature that will help you track incorrect uses of UIKit from a background thread. <p>Starting with this release, debug builds of your application will throw a <a href="http://iosapi.xamarin.com/?link=T%3aMonoTouch.UIKit.UIKitThreadAccessException">UIKitThreadAccessException</a> exception if you try to invoke a UIKit method from a background thread. <p>This is what the exception will look like: <pre> MonoTouch.UIKit.UIKitThreadAccessException: UIKit Consistency error: you are calling a UIKit method that can only be invoked from the UI thread. at MonoTouch.UIKit.UIApplication.EnsureUIThread at MonoTouch.UIKit.UIView.get_Subviews at Sample.AppDelegate.<FinishedLaunching>m__0 </pre> <p>This is a fabulous tool. It founds bugs in my own code within a few seconds of me using my own software. Sometimes the bug is right there for you to see, but do not notice the mistake. <h2>The Whitelist</h2> <p>Over time, Apple has made some of UIKit APIs thread safe. This means that there are certain APIs that can safely be used concurrently by both the main thread and background threads. Those are documented in MonoTouch's documentation <p>Our list is based on what Apple has publicly documented as thread safe in different forums. It is likely that more types and methods will become thread safe in the future, and when that happens, MonoTouch will will remove the particular check for debug builds for it. <h2>Controlling The Thread Safety Check</h2> <p>By default MonoTouch is configured to perform the thread checks only on debug builds of your software. If you want to have these checks performed also during release builds, you can pass the <tt>--force-thread-check</tt> to the mtouch compiler. <p>You might want to disable this check for a couple of reasons. You might have a big infringing codebase that is mostly working for you now, and can not afford to go fix these bugs right away. Or you could get confirmation from Apple that it is safe to call an API from a background thread. With MonoTouch, we have opted to be conservative and go by what is documented, but it is very possible that there are some APIs that are thread safe and just have not been documented as such. <p>You can disable the feature for debug builds by passing the <tt>--disable-thread-check</tt> flag to the compiler, or you can do this at runtime by changing the value of <a href="http://iosapi.xamarin.com/?link=F%3aMonoTouch.UIKit.UIApplication.CheckForIllegalCrossThreadCalls">UIApplication.CheckForIllegalCrossThreadCalls</a>, like this: <pre class="code-csharp"> // // Disable UIKit thread checks for a couple of methods // var previous = UIApplication.CheckForIllegalCrossThreadCalls; UIApplication.CheckForIllegalCrossThreadCall = false; // Perform some UIKit calls here foo.Bar = 1; // Restore UIApplication.CheckForIllegalCrossThreadCalls = previous; </pre> <h2>Adding Your Own Checks</h2> <p>If are building a library that wants to enforce the same kind of checks, you should call the new <a href="http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIApplication.EnsureUIThread()">UIApplication.EnsureUIThread</a> from your code to perform these checks. http://tirania.org/monomac/archive/2012/Sep-10.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Sep-10.html Mon, 10 Sep 2012 17:03:00 -0500 Feedback Requested: Binding NSAttributedString <p>As NSAttributedString plays a big role, I have been trying to figure out a way of improving the process by which NSAttributedString are created from C#. <h2>Status Today</h2> <p>While we support the NSDictionary-based approach of creating the attributed needed for an attributed string, like this: <pre class="code-csharp"> var attrs = new NSMutableDictionary () { { NSAttributedString.FontAttributeName, UIFont.FromName ("Heletica 14") }, { NSAttributedString.ForegroundColorAttributeName, UIColor.Black } }; var myString = new NSAttributedString ("Hello", attrs); </pre> <p>If you ignore the fact that Helvetica 14 is an uninspiring and inconsequential font, the example above is error prone. <p>Developers can pass a UIColor where a UIFont was required, or a number or anything else. They also have no idea what values are acceptable unless they take a trip to the documentation and find out which values are allowed, and the types of their values. <h2>The Standard Choice</h2> <p>What we have historicallly in situations like this is to create a helper, strongly typed class. This allows the IDE to provide intellisense for this situation, explicitly listing the types allowed and ensuring that only the correct values are set. If we use this approach, we would introduce a new class, let us say "NSStringAttributes": <pre class="code-csharp"> var attrs = new NSStringAttributes () { Font = UIFont.FromName ("Heletica 14"), ForegroundColor = UIColor.Black }; var myString = new NSAttributedString ("Hello", attrs); </pre> <p>The only problem that I have with this approach is that now we have two classes: NSAttributedString which is the actual string with the given attribute and a class that has a name that resembles too much NSAttributedString. <p>My concern is not that seasoned developers would be confused between NSAttributedString and NSStringAttributes, but that developers new to the platform would rightfully ask why they need to know the differences about this. <p>The upside is that it follows the existing pattern in MonoTouch and MonoMac: use a strongly typed class, which internally produces the NSDictionary on demand. <h2>Giving NSAttributedString special powers</h2> <p>Another option is to give NSAttributedString special powers. This would allow NSAttributedString instances to be configured like this: <pre class="code-csharp"> var myString = new NSAttributedString ("Hello") { Font = UIFont.FromName ("Helvetica 14"), ForegroundColor = UIColor.Black } </pre> <p>To support the above configuration, we would have to delay the actual creation of the NSAttributedString from the constructor time until the object is actually used. <p>This would allow the user to set the Font, ForegroundColor and other properties up until the point of creation. This would require the NSAttributedString type to be treated specially by the MonoTouch/MonoMac bindings. <p>It would also make the NSMutableAttributedString feel a bit better to use: users could make changes to the attributed string all day long, and apply changes to the various properties for the entire span of the text with a simple property value: <pre class="code-csharp"> var myString = new NSMutableAttributedString ("Hello"); // This: myString.AddAttribute ( NSAttributedString.ForegroundColorAttributeName, UIColor.Red, new NSRange (0, myString.Length)); // Would become: myString.ForegroundColor = UIColor.Red; </pre> <p>There are a couple of downsides with the above approach. The actual attributes used for this string configuration would not be shared across different NSAttributedStrings, so for some code patterns, you would be better off not using this syntax and instead using the NSStringAttributes class. <p>The other downside is that NSAttributedString properties could be set only up to the point of the string being used. Once the string is used, the values would be set in stone, and any attempt to change them would throw an exception, or issue a strongly worded message on the console. <p>And of course, the improved NSMutableAttributedString API improvements could be done independently of the property setters existing in the base class. <h2>Others?</h2> <p>Can anyone think of other strongly typed approaches to simplify the use of NSAttributedStrings that are not listed here? <h2>Update</h2> <p>Thanks for your excellent feedback! It helped us clarify what we wanted to do with the API. We are going to go with the "Standard Choice", but with a small twist. <p>We came to realize that NSAttributedString is just a string with attributes, but the attributes are not set in stone. It is really up to the consumer of the API to determine what the meaning of the attributes are. <p>We had a constructor that took a CTStringAttributes parameter which is used when you render text with CoreText. <p>What we are going to do is introduce a UIStringAttributes for iOS to set UIKit attributes and an NSStringAttributes for AppKit that will have the same behavior: they will be strongly typed classes that can be passed as a parameter to the NSAttributedString constructor. <p>So we will have basically three convenience and type safe constructors based on what you will be using the NSAttributedString with as well as the standard NSDictionary constructor for your own use: <pre class="code-csharp"> public class NSAttributedString : NSObject { public NSAttributedString (string str, NSDictionary attrs); public NSAttributedString (string str, CTStringAttributes attrs); // iOS only public NSAttributedString (string str, UIStringAttributes attrs); // OSX only public NSAttributedString (string str, NSStringAttributes attrs); } </pre> <p>We will also provide convenience "GetAttributes" methods for all platforms: <pre class="code-csharp"> public class NSAttributedString : NSObject { public CTStringAttributes GetUIKitAttributes (); // Only on iOS public UIStringAttributes GetUIKitAttributes (); // Only on OSX public NSStringAttributes GetUIKitAttributes (); } </pre> <P>Finally, we loved Mark Rendle's proposal of using default parameters and named parameters for C#. This actually opened our eyes to a whole new set of convenience constructors that we can use to improve both the MonoTouch and MonoMac APIs. <p>This comes from a Sample I was working on: <pre class="code-csharp"> var text = new NSAttributedString ( "Hello world", font: GetFont ("HoeflerText-Regular", 24.0f), foregroundColor: GetRandomColor (), backgroundColor: GetRandomColor (), ligatures: NSLigatureType.All, kerning: 10, // Very classy! underlineStyle: NSUnderlineStyle.Single, shadow: new NSShadow () { ShadowColor = GetRandomColor (), ShadowOffset = new System.Drawing.SizeF (2, 2) }, strokeWidth: 5); #endif </pre> <p>The only open question is whether the parameter names in this case should be camelCase, or start with an uppercase letter (font vs Font and foregroundColor vs ForegroundColor). <p>The result on screen are beautiful! http://tirania.org/monomac/archive/2012/Aug-24.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Aug-24.html Fri, 24 Aug 2012 17:47:00 -0500 MonoMac Updates <p>Over the last couple of months we have been silently updating both the MonoMac APIs as well as the IDE support for it. All of the features that I <a href="http://tirania.org/monomac/archive/2012/Mar-06.html">talked back in March</a> are now publicly available. <p>More code is now shared with the MonoTouch infrastructure, which means that every time that we improve our MonoTouch IDE support, MonoMac will be improved as well. <h2>MonoDevelop Improvements for MonoMac</h2> <p>The latest version of MonoDevelop that we released contains a significant update for developers. In the past, you had to use a one-off dialog box to create packages, installers and prepare an app for AppStore distribution. <p>With the latest release, we have now turned these configuration options into settings that are part of the project. This means that you can now configure these based on your selected project configuration, you can automate the builds, save your settings and most importantly, you have many more options at your disposal: <center> <img src="http://tirania.org/pictures/monomac-packaging-2012.png"> <p>MonoMac packaging settings. </center> <p>Plenty of the settings that go into Info.plist are now available directly in the project settings as well as the support for maintaining your iCloud keys and sandbox requirements: <center> <img src="http://tirania.org/pictures/monomac-settings-2012.png"> <p>MacOS Project Settings. </center> <p>We also brought the MonoTouch Info.plist editor into the IDE, this allows you to maintain your Info.plist directly from the IDE. It is also a convenient place to declare which file types your application exports and consumes: <center> <img src="http://tirania.org/pictures/monomac-infoplist-2012.png"> <p>Info.plist Editor. </center> <h2>New Launcher</h2> <p>In the past we used a shell script to start your program, the shell script would set a few environment variables and invoke Mono with your initial assembly. <p>We now ship a binary launcher that links with the Mono runtime and fixes several long standing issues involving application launching. <h2>Getting the latest MonoMac</h2> <p>To get the latest support for MonoMac, merely download MonoDevelop 3.0.4.1 (our latest build available from <a href="http://www.monodevelop.com">monodevelop.com</a> and you will get the entire package for Mac development. <h2>Samples</h2> <p>New samples in MonoMac show how to <a href="https://github.com/mono/monomac/tree/master/samples/AnimatedClock">use CoreAnimation to animate custom C# properties</a>. Our own MacDoc sample which was supposed to be just a simple demo of WebKit, MonoMac and MonoDoc has turned into a full fledged documentation browser which is now part of our own products (MonoTouch). http://tirania.org/monomac/archive/2012/Jul-27.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Jul-27.html Fri, 27 Jul 2012 13:49:00 -0500 Key-Value-Observing on MonoTouch and MonoMac <p>This morning Andres came by IRC asking questions about Key Value Observing, and I could not point him to a blog post that would discuss the details on how to use this on C#. <p> <a href="https://developer.apple.com/library/mac/#documentation/cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html">Apple's Key-Value Observing</a> document contains the basics on how to observe changes in properties done to objects. <p>To implement Key-Value-Observing using MonoTouch or MonoMac all you have to do is pick the object that you want to observe properties on, and invoke the "AddObserver" method. <p>This method takes a couple of parameters: an object that will be notified of the changes, the key-path to the property that you want to observe, the observing options and a context object (optional). <p>For example, to observe changes to the "bounds" property on a UIView, you can use this code: <pre class="code-csharp"> view.AddObserver ( observer: this, keyPath: new NSString ("bounds"), options: NSKeyValueObservingOptions.New, context: IntPtr.Zero); </pre> <p>In this example, I am using the C# syntax that uses the Objective-C style to highlight what we are doing, but you could just have written this as: <pre class="code-csharp"> view.AddObserver ( this, new NSString ("bounds"), NSKeyValueObservingOptions.New, IntPtr.Zero); </pre> <p>What the above code does is to add an observer on the "view" object, and instructs it to notify this object when the "bounds" property changes. <p>To receive notifications, you need to override the ObserveValue method in your class: <pre class="code-csharp"> public override void ObserveValue (NSString keyPath, NSObject ofObject, NSDictionary change, IntPtr context) { var str = String.Format ( "The {0} property on {1}, the change is: {2}", keyPath, ofObject, change.Description); label.Text = str; label.Frame = ComputeLabelRect (); } </pre> <p>This is what the app shows if you rotate your phone: <center> <img src="http://tirania.org/s/5a85f5d0.png"> </center> <p>The complete sample has been uploaded to <a href="https://github.com/xamarin/monotouch-samples/tree/master/KeyValueObserving">GitHub</a>. http://tirania.org/monomac/archive/2012/Apr-19.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Apr-19.html Thu, 19 Apr 2012 22:12:00 -0500 Call for Comments: Strongly Typed Notifications <p>I am adding support for strongly typed notifications to MonoTouch and MonoMac. The idea behind this is to take guesswork, trips to the documentation and trial and error from using notifications on iOS and MacOS. <p>The process is usually: (a) find the right notification; (b) look up apple docs to see when the notification is posted; (c) look up each of the keys used to retrieve the data from the dictionary. <p>Currently, listening to a notification for a keyboard-will-be-shown notification looks like this in MonoTouch: <pre> void DoSomething ( UIViewAnimationCurve curve, double duration, RectangleF frame) { // do something with the above } var center = NSNotificationCenter.DefaultCenter; center.AddObserver (UIKeyboard.WillShowNotification, PlaceKeyboard); [...] void PlaceKeyboard (NSNotification notification) { // Get the dictionary with the interesting values: var dict = notification.UserInfo; // Extract the individual values var animationCurve = (UIViewAnimationCurve) (dict [UIKeyboard.AnimationCurveUserInfoKey] as NSNumber).Int32Value; double duration = (dict [UIKeyboard.AnimationDurationUserInfoKey] as NSNumber).DoubleValue; RectangleF endFrame = (dict [UIKeyboard.FrameEndUserInfoKey] as NSValue).RectangleFValue; DoSomething (animationCurve, duration, endFrame) } </pre> <p>Currently we map the Objective-C constant "FooClassNameNotification" into the C# class "Foo" as the member "NameNotification" of type NSString. <p>What we want to do is to expose the notifications as strongly typed C# events. This will provide auto-complete support in the IDE to produce the lambdas or helper methods, auto-complete for all the possible properties of the notification, strong types for the data provided and live documentation for the values in the notification. <p>This means that the above code would instead be written like this: <pre> var center = NSNotificationCenter.DefaultCenter; center.Keyboard.WillShowNotification += PlaceKeyboard; void PlaceKeyboard (object sender, KeyboardShownEventArgs args) { DoSomething (args.AnimationCurve, args.Duration, args.EndFrame); } </pre> <p>The question is where should these notifications be exposed in the API? In the example above we do this by the event "WillShowNotification" on a class "Keyboard" inside the "NSNotificationCenter". We have a few options for this. <p>We could host the notification in the class that defines the notification, but we would have to come up with a naming scheme to avoid the name clash with the existing NSString constant: <pre> class UIKeyboard { public NSString WillShowNotification { get; } // replace "Notification" with the class name: public event EventHandler<KeyboardShowEventArgs> WillShowKeyboard; // prefix the event: public event EventHandler<KeyboardShowEventArgs> KeyboardWillShow; // plain, does not work on all types though: public event EventHandler<KeyboardShowEventArgs> WillShow; } // Consumer code would be one of: UIKeyboard.WillShowKeyboard += handler; UIKeyboard.KeyboardWillShow += handler; UIKeyboard.WillShow += handler; </pre> <p>Another option is to add everything into NSNotificationCenter: <pre> class NSNotificationCenter { // Existing implementation public event EventHandler<KeyboardShowEventArgs> UIKeyboardWillShow; // Another 141 events are inserted here. } // Consumer code would be: NSNotificationCenter.DefaultCenter.UIKeyboardWillShow += handler; </pre> <p>Another option is to partition the notifications based on their natural host, this is my personal favorite, but could be harder to find with the IDE using code completion: <pre> class NSNotificationCenter { public static class Keyboard { public static event EventHandler<KeyboardShowEventArgs> WillShow; } } // Consumer code would be: NSNotificationCenter.Keyboard.WillShow += handler; </pre> <p>All of these proposals have one potential problem: they would all assume that all of these interesting notifications are always posted into the NSNotificationCenter.DefaultCenter. <p>Apple's documentation does not seem to suggest that any of the iOS notifications are posted anywhere but the DefaultCenter. I could not find on GitHub any code that would use anything but the DefaultCenter. <p>On MacOS the InstantMessage framework posts notifications to its own notification center. We could just bind those events to this specific NSNotificationCenter. <p>Thoughts? http://tirania.org/monomac/archive/2012/Apr-12.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Apr-12.html Thu, 12 Apr 2012 21:06:00 -0500 MonoMac Updates <p>We have been hard at work at improving the MonoMac API to allow .NET developers to create native Mac applications using C#, F#, IronPython or their favorite .NET language. <p>There are couple of goodies coming on our next release of MonoMac: our Lion support is shapping up and we have been dogfooding this ourselves with our own apps. <p>One of our sample apps, a simple front-end to the Mono Documentation backend is now complete enough that we are going to deprecate the Gtk+ version of it and replace it with the native version of it. <p>MacDoc now has several new features <p><b>Apple documentation integration:</b> MacDoc will now download the Apple docs if they are not available and blend its contents with our documentation and replace the Objective-C samples with C# samples. Amazing! <p><b>Full text indexing:</b> the documentation browser is using Lucene to index all of the contents and allow you to quickly find the materials that you are looking for. <center> <img src="http://tirania.org/s/69c08dbc.png"> </center> <p><b>Conceptual Index:</b> in addition to the full text search, we generate a curated version of the APIs that are useful for performing search-as-you-type in the documentation browser. This is useful to find APIs by class, by method name and also by Objective-C selector. This means that you can now search for Objetive-C selectors in our documentation, and you will get the actual mapping to the C# method. <center> <img src="http://tirania.org/s/1cb8b516.png"> </center> <p>Supports Lion documents, saved state and bookmarks. <p>We extended the ECMA XML format so it now renders images for our docs: <center> <img src="http://tirania.org/s/94a15a6a.png"> </center> <p>The source code is available now in <a href="https://github.com/mono/monomac/tree/master/samples/macdoc">GitHub</a> and will be shipping in the upcoming MonoDevelop 2.8.8 release. http://tirania.org/monomac/archive/2012/Mar-06.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Mar-06.html Tue, 06 Mar 2012 21:34:00 -0500 Bubbles <p>Recently one of our customers asked about how to implement a conversation display similar to the iOS SMS/Messages display. You can find the <a href="https://github.com/xamarin/monotouch-samples/tree/master/BubbleCell">BubbleCell sample</a> in our Github repository. <p>This is what the conversation looks like: <center> <img src="http://tirania.org/s/c38c418a.png"> </center> <p>To implement this, I used iOS's UITableView as it already provides a lot of the functionality that we need for this. What I did was to write a custom UITableViewCell that can render bubbles with their text. <p>I wrote both a MonoTouch.Dialog Element that you can host in your DialogViewController as well as a custom UITableCellView which can be reused by those using UITableViews directly. <p>This is how you could populate the initial discussion inside MonoTouch.Dialog: <pre class="code-csharp"> Section chat; var root = new RootElement ("Chat Sample") { (chat = new Section () { new ChatBubble (true, "This is the text on the left, what I find fascinating about this is how many lines can fit!"), new ChatBubble (false, "This is some text on the right"), new ChatBubble (true, "Wow, you are very intense!"), new ChatBubble (false, "oops"), new ChatBubble (true, "yes"), }) };</pre> <p>And this is how you would add a new element to the conversation: <pre class="code-csharp"> chat.Section.Add ( new ChatBubble (false, "I want more cat facts"));</pre> <h2>Implementation</h2> <p>Bubble rendering is implemented in Bubble.cs and contains both the UITableViewCell as well as the element. It follows the pattern for creating UITableViewCells that I <a href="http://tirania.org/monomac/archive/2011/Jan-18.html">documented before</a>. <p>Each cell is made up of two views: one contains a UIImageView that paints the bubble and the other one contains the text to render inside the bubble. <p>This is what the two bubbles images look like: <center> <img src="http://tirania.org/s/dba416d6.png"> </center> <p>We load these using UIImage.FromFile and then use the iOS 5.0 <a href="http://iosapi.xamarin.com/?link=M%3aMonoTouch.UIKit.UIImage.CreateResizableImage(MonoTouch.UIKit.UIEdgeInsets)">UIImage.CreateResizableImage</a> method to create a UIImage that can be stretched on demand. To create the resizable image we need to tell CreateResizableImage the region of the image that can be stretched. Anything outside of the UIEdgeInset will be kept as-is: <pre class="code-csharp"> left = bleft.CreateResizableImage (new UIEdgeInsets (10, 16, 18, 26)); right = bright.CreateResizableImage (new UIEdgeInsets (11, 11, 17, 18));</pre> <p>This will stretch the region highlighted in red, while rendering the external border as-is: <center> <img src="http://tirania.org/s/bstretch.png"> </center> <p>With the above code, the image will be rendered in a variety ways depending on the Frame that is assigned to the UIImageView that hosts our resizable UIImage: <center> <img src="http://tirania.org/s/ff8a3a6c.png"> </center> <p>The only remaining interesting bit in the code is to configure our UILabel properly. We want to set its BackgroundColor to UIColor.Clear to avoid painting the background in a solid color and we also specify that the text should be word-wrapped if it does not fit in a single line: <pre class="code-csharp"> label = new UILabel (rect) { LineBreakMode = UILineBreakMode.WordWrap, Lines = 0, Font = font, BackgroundColor = UIColor.Clear }; </pre> <p>Finally in our LayoutSubViews method we must compute the proper sizes for the bubbles and the text that goes in them. I made it so the bubbles did not take the entire space in a row. Instead they take 70% of the row to give a similar effect to the rendering of the iOS messages UI. The code is pretty straight-forward: <pre class="code-csharp"> public override void LayoutSubviews () { base.LayoutSubviews (); var frame = ContentView.Frame; var size = GetSizeForText (this, label.Text) + BubblePadding; imageView.Frame = new RectangleF (new PointF (isLeft ? 10 : frame.Width-size.Width-10, frame.Y), size); view.SetNeedsDisplay (); frame = imageView.Frame; label.Frame = new RectangleF (new PointF (frame.X + (isLeft ? 12 : 8), frame.Y + 6), size-BubblePadding); } </pre> http://tirania.org/monomac/archive/2012/Jan-30.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2012/Jan-30.html Mon, 30 Jan 2012 18:22:00 -0500 Styling your controls in MonoTouch on iOS 5 <p>Starting with iOS 5 it is possible to more easily style your UIViews. Apple did this by exposing a new set of properties on most views that can be tuned. For example, to configure the TintColor of a UISlider, you would write: <pre> var mySlider = new UISlider (rect); mySlider.ThumbTintColor = UIColor.Red; </pre> <p>You can also set the color globally for all instances of UISlider, you do this by assigning the styling attributes on the special property "Appearance" from the class you want to style. <p>The following example shows how to set the Tint color for all UISliders: <pre> UISlider.Appearance.ThumbTintColor = UIColor.Red; </pre> <p>It is of course possible to set this on a per-view way, <p>The first time that you access the "Appearance" static property on a stylable class a UIAppearance proxy will be created to host the style changes that you have requested and will apply to your views. <p>In Objective-C the Appearance property is untyped. With MonoTouch we took a different approach, we created a strongly typed UIXxxxAppearance class for each class that supports styling. Our generated UIXxxxxAppearance class is strongly typed, which allows users to use intellisense to easily discover which properties are avaialble for styling. <p>We also created a hierarchy that reflects the inherited appearance properties, this is the class hierarchy for the <a href="http://docs.go-mono.com/index.aspx?link=T%3aMonoTouch.UIKit.UISlider%2bUISliderAppearance">UISLider.UISliderAppearance</a> class: <center> <img src="http://tirania.org/s/87cf5019.png"> </center> <p>The properties exposed by UISlider for example are: <pre> public class UISliderAppearance { public virtual UIColor BackgroundColor { get; set; } public virtual UIColor MaximumTrackTintColor { get; set; } public virtual UIColor MinimumTrackTintColor { get; set; } public virtual UIColor ThumbTintColor { get; set; } } </pre> <p>MonoTouch also introduced support for styling your controls only when they are hosted in a particular part of the hierarchy. You do this by calling the static method AppearanceWhenContainedIn which takes a variable list of types, it works like this: <pre> var style = UISlider.AppearanceWhenContainedIn (typeof (SalesPane), typeof (ProductDetail)); style.ThumbTintColor = UIColor.Red; </pre> <p>In the above sample the style for the ThumbTintColor will be red, but only for the UISliders contained in ProductDetail view controllers when those view controllers are being hosted by a SalesPane view controller. Other UISliders will not be affected. <p>Both the Appearance static property and the AppearanceWhenContainedIn static method have been surfaced on every UIView that supports configuring its style. Both of them return strongly typed classes that derive from UIAppearance and expose the exact set of properties that can be set. <p>This is different from the weakly typed Objective-C API which makes it hard to discover what can be styled. http://tirania.org/monomac/archive/2011/Oct-14.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Oct-14.html Fri, 14 Oct 2011 22:38:00 -0500 MonoTouch 5.0 is out <p>Yesterday <a href="http://blog.xamarin.com/2011/10/12/monotouch-5-with-ios-5-support/">we released MonoTouch 5.0</a>, the companion to Apple's iOS 5.0 release. <p>Apple tends to ship Objective-C APIs that are configured through an NSDictionary instance containing configuration keys. With MonoTouch 5.0, we continued our work to <a href="http://tirania.org/monomac/archive/2010/Dec-01.html">improve over NSDictionary-based bindings</a> by creating strongly-typed versions of those APIs. <p>In the next couple of days, I will be sharing some of the new features in iOS 5.0 and how to take advantage of those using C#. <p>Meanwhile, our documentation team has produced an amazing <a href="http://docs.xamarin.com/ios/tutorials/Introduction_to_iOS_5">Introduction to iOS 5.0 for C# developers</a> and put together some samples showing how to use some of the new features in iOS 5: <ul> <li><a href="http://docs.xamarin.com/@api/deki/files/323/=Storyboard.zip">Storyboard</a>: shows how to use Storyboards from C# and showcases the integration between Xcode 4 and MonoDevelop 2.8 <li><a href="http://docs.xamarin.com/@api/deki/files/320/=CoreImage.zip">CoreImage</a>: shows our bubilicious strongly-typed API for CIFilters, it is in my opinion, a huge usability upgrade over the NSDictionary-based approach. <li><a href="http://docs.xamarin.com/@api/deki/files/321/=iCloud.zip">iCloud</a>: Basic iCloud use. <li><a href="http://docs.xamarin.com/@api/deki/files/324/=Twitter.zip">Twitter</a>: Post new tweets and query twitter for data. <li><a href="http://docs.xamarin.com/@api/deki/files/322/=Newsstand.zip">Newsstand</a>: A complete sample showing how you can integrate with the new Newsstand APIs to publish your own periodicals. We wont be submitting this sample for the Apple Design Awards, but it shows how to use the framework. </ul> http://tirania.org/monomac/archive/2011/Oct-13.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Oct-13.html Thu, 13 Oct 2011 16:28:00 -0500 TestFlight support in MonoDevelop <p>We have just released for <a href="http://docs.xamarin.com/ios/tutorials/TestFlight_Support">TestFlight support</a> in MonoDevelop. <p>This makes it simpler for developers to deploy their Ad-Hoc builds directly to Testflight, we added a "Publish to TestFlight" option: <center> <img src="http://docs.xamarin.com/@api/deki/files/271/=testflight-1.png"> </center> <p>The first time you upload to TestFlight you must provide your authentication tokens: <center> <img src="http://docs.xamarin.com/@api/deki/files/268/=testflight-4.png"> </center> <p>And after that, the IDE takes care of the rest: <center> <img src="http://docs.xamarin.com/@api/deki/files/266/=testflight-6.png"> </center> <p>This is built on top of our enhanced <a href="http://docs.xamarin.com/ios/tutorials/IPA_Support_-_Ad_Hoc_and_Enterprise_Deployment">IPA Packaging support</a> in the same release. http://tirania.org/monomac/archive/2011/Sep-29.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Sep-29.html Thu, 29 Sep 2011 14:12:00 -0500 Sales Force app built with MonoTouch <p>I do not blog very often about apps built with MonoTouch, but <a href="http://www.justenough.com/NetSuite/MobileSFA/">this application</a> is drop-dead gorgeous. <p>It is a tool designed to be used by the sales force of a company. <p>You can download the app from the Apple AppStore and try it on "demo" mode. What I love about this application is how they took advantage of UIKit and CoreAnimation to create a beautiful enterprise app. It does not stop there, they use everything iOS has to offer: <center> <img src="http://a3.mzstatic.com/us/r1000/063/Purple/f5/ed/83/mzl.gtaqidjm.480x480-75.jpg"> <p> <img src="http://a2.mzstatic.com/us/r1000/061/Purple/37/da/11/mzl.wkykqmxl.480x480-75.jpg"> </center> <p>Enterprise software has a reputation for being hostile to end-users. This shows that you can create great end-user software for users in the enterprise. If you were looking for inspiration for your own enterprise apps, this is the app to look for. http://tirania.org/monomac/archive/2011/Aug-12.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Aug-12.html Fri, 12 Aug 2011 20:28:00 -0500 MonoMac add-in for MonoDevelop <p>After a small hiatus we are back. <p>If you have been using MonoMac to build MacOS applications, we have just released an update to the MonoDevelop.MonoMac add-in that should fix the problem with packaging your applications on Lion. <p>This update just contains a critical fix and delivers the add-in to all three MonoDevelop platforms in use today: our stable MonoDevelop 2.4, the 2.6beta3 and for the fearless among you MonoDevelop/master. <p>This was just the first step in maintaining the add-in. I had to sort out the build setup for all three branches and the pipeline to deliver the updates. Now that I got things in place, I will be able to fix some of the other problems that have been reported. <p>If you are running into problems with MonoMac, please file your bugs at the new home for the Mono bug reports at <a href="http://bugzilla.xamarin.com">http://bugzilla.xamarin.com</a>. http://tirania.org/monomac/archive/2011/Aug-03.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Aug-03.html Wed, 03 Aug 2011 21:40:00 -0500 Glass button for iPhone <p>Since iOS does not provide a default glossy button implementation I wrote my own, based mostly on looking at a screenshot of Apple's own. <p>Some folks have been using the <a href="http://conceptdev.blogspot.com/2010/08/uiglassbutton-generator-in-monotouch.html">UIGlassButton generator</a>, but I have wanted for a while to have this functionality avaialble at runtime, and not depend on pre-generated images, these are created at runtime, and behave just like a regular button: <center> <img src="http://tirania.org/pictures/mt-glass-button.png"> </center> <p>You can find <a href="https://github.com/migueldeicaza/MonoTouch.Dialog/blob/master/MonoTouch.Dialog/Utilities/GlassButton.cs">my implementation</a> as part of <a href="https://github.com/migueldeicaza/MonoTouch.Dialog/blob/master/MonoTouch.Dialog">MonoTouch.Dialog</a> on github. <p>This is how you would use it, and how you can customize some of its elements: <pre class="code-csharp"> var b = new GlassButton (bounds) { Font = UIFont.BoldSystemFontOfSize (22), NormalColor = UIColor.Green, HighlightedColor = UIColor.Red }; b.SetTitle ("Dismiss", UIControlState.Normal); container.AddSubview (b); </pre> http://tirania.org/monomac/archive/2011/Apr-08.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Apr-08.html Fri, 08 Apr 2011 14:19:00 -0500 MonoTouch 4.0 <p><img src="http://tirania.org/pictures/vintage-monotouch-logo.png" align="right">We just released MonoTouch 4.0, a product to build iOS applications using C# and .NET. We also released our new <a href="http://tirania.org/blog/archive/2011/Apr-06.html">Mono for Android</a> product. <h2>New in MonoTouch 4.0</h2> <p>MonoTouch 4.0 is a major upgrade to our product as it upgrades the Mono runtime engine from the old, trusted and friendly Mono 2.6 to the latest and greatest <a href="http://www.mono-project.com/Release_Notes_Mono_2.10">Mono 2.10</a> core, these are some of the new features available as part of this upgrade: <ul> <li>Parallel Frameworks for C#: Great APIs for building multi-threaded software. Not only this is great for iPad 2 users and developers, but it also simplifies just plain multi-threaded programming by exposing Futures, Tasks and Parallel LINQ to the developer. <li>LLVM Compiler Support: In addition to the fast Mono compilation engine, MonoTouch can now also use LLVM to create optimized builds. When you build MonoTouch applications using LLVM your executables will run faster, they will be smaller, and you can optionally opt into generating the nimbler ARMv7 or Thumb code (fat binaries are also supported). <p><b>Example:</b> My own <a href="http://tirania.org/tweetstation/">TweetStation distribution</a> went from 8 megs to 6 megs using Thumb + ARMv7 support. A very significant gain. <li>C# 4.0 and .NET 4.0: This release comes with the latest incarnation of the C# language as well as exposing the new .NET 4.0 APIs (many new functional constructs make for nicer looking code, like all the IEnumerable<Foo> enabled-methods in System.IO). <p>There is one important limitation: C# 4.0 dynamic support is not functional, since it requires dynamic code generation to work. <li>Upgraded WCF stack: We still consider this a preview of the full WCF but has been expanded significantly. <li>All new iOS 4.3 APIs have been exposed. <li>NSDecimal, NSDecimalNumber are now exposed (mostly for the sake of CorePlot :-) <li>Many new convenience APIs have been introduced. </ul> <p>For a full detailed list of changes, see <a href="http://monotouch.net/Releases/MonoTouch_4/MonoTouch_4.0.0">our MonoTouch 4.0 Release Notes</a>. <h2>Resources</h2> <p>The best source of information on parallel programming with Parallel FX is the free <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=86b3d32b-ad26-4bb8-a3ae-c1637026c3ee&displaylang=en">Patterns for Parallel Programming: Understanding and Applying Parallel Patterns with the .NET Framework 4</a>. <p>This is a brilliant document. Whether you use .NET or not, this is a recommended reading for everyone. <p>In addition to the <a href="http://www.amazon.com/dp/047063782X/ref=as_li_ss_til?tag=tiraniaorg-20&camp=213381&creative=390973&linkCode=as4&creativeASIN=047063782X&adid=12Z07C36B4TXR7Y4QRM4&">Programming iPhone with MonoTouch book</a> there are two new books about to hit the shelves <a href="http://www.amazon.com/gp/product/1430231742/ref=as_li_ss_tl?ie=UTF8&tag=tiraniaorg-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=1430231742">Developing C# Apps for iPhone and iPad using MonoTouch: iOS Apps Development for .NET Developers</a>: an incredibly in-depth book from Brian Costanich that I have had the privilege to read in advance. This book will come out in only 3 weeks. <p>If you are more of a hands-on kind of guy, later in the year, Mike Bluestein's <a href="http://www.amazon.com/gp/product/0321719921/ref=as_li_ss_tl?ie=UTF8&tag=tiraniaorg-20&linkCode=as2&camp=1789&creative=390957&creativeASIN=0321719921">Learning MonoTouch: A Hands-On Guide to Building iPhone and iPad Applications with C# and .NET</a> is coming out. <h2>Next Steps</h2> <p>We are currently hard at work to add support to MonoDevelop to work with the new XCode 4. <p>With XCode 4, Apple removed Interface Builder as a standalone tool. We should have a beta in a couple of weeks of the solution we came up with. http://tirania.org/monomac/archive/2011/Apr-06.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Apr-06.html Wed, 06 Apr 2011 16:20:00 -0500 MonoMac 1.0 is out <p><a href="http://tirania.org/blog/archive/2010/Apr-19.html">Almost a year ago</a> we started building a set of Mono bindings for building native MacOS X applications. <p>Our original goals were modest: bind enough of AppKit that you could build native desktop applications for OSX using C# or your favorite .NET language. We leveraged a lot of the code that we built for MonoTouch our binding to the CocoaTouch APIs. <p>During the year, the project picked up steam, we got plenty of contributions to MonoMac and grew beyond the original conservative goals. <p>In a year we: <ul> <li>Created a beautiful library that <a href="http://www.mono-project.com/MonoMac#Background">blends the worlds of C# and MacOS X</a> APIs. <li><a href="http://mjhutchinson.com/journal/2010/06/09/monomac_in_monodevelop">Created a MonoDevelop add-in</a> that helps developers get started with Mac development in minutes. <li>Integrated the MonoDoc system into MonoDevelop, to provide developers with documentation on the flight as they type their code. Detailed method information, parameter use and type information is available as you type your code in unobtrusive windows. <li><a href="http://www.mono-project.com/MonoMacPackager">Created a packager</a> that turns your programs into self-contained OSX Packages with no external dependencies on Mono and can be deployed to the Apple App Store. <li>Created a linker that lets you strip out any functionality your application might not need to reduce your executable size. <li>Created a <a href="http://lists.ximian.com/pipermail/mono-osx/">great community of developers</a> that love C#, .NET and MacOS. For some of us, this is a step closer to heaven. <li>Created a <a href="https://github.com/mono/monomac/tree/master/samples">big pool of samples</a> for developers to learn from, and for us to exercise the API and ensure that the resulting library was a delight to use. <li>Created various <a href="http://www.mono-project.com/MonoMac#Tutorials">tutorials</a> on how to build applications with C# on the Mac. <li>Built an <a href="http://mono.ximian.com/monomac-docs/">online documentation mash-up</a> between our API and Apple's web documentation </ul> <p>Some statistics about the MonoMac binding: <ul> <li>1,155 C# classes and 31 C# structures <li>376 enumerations <li>123 C# delegate data types <li>16,556 methods, properties and events exposed </ul> <p>In addition to that, MonoMac <a href="http://mono.ximian.com/monomac-docs/MonoMac.OpenGL">bundles a modified version</a> of the amazing <a href="http://www.opentk.com/">OpenTK 1.0</a>. We took the liberty (and by "we" I mean, the amazing Kenneth Pouncey) of fine-tuning the implementation for MonoMac use. <h2>Getting MonoMac 1.0</h2> <p>If you already have MonoDevelop installed, just update your MonoMac Add-In. If you do not have MonoDevelop installed, follow our <a href="http://www.mono-project.com/MonoMac#Obtaining_MonoMac">friendly instructions</a>. <h2>Contributors</h2> <p>MonoMac would not have been possible without the help of our great contributors, this is the team: <p>Main bindings: <ul> <li>Geoff Norton <li>Miguel de Icaza <li>Jonathan Pryor <li>Michael Hutchinson </ul> <p>Contributors: <ul> <li>Alexander Shulgin (WebKit DOM) <li>James Clancey (AppKit contributions) <li>Kenneth Pouncey (API, samples) <li>Maxi Combina (WebKit events, sample) <li>Regan Sarwas (PdfKit, ImageKit, NSColor, NSGradient, NSBezierPath, samples) <li>Ashok Gelal (CoreWlan) </ul> <h2>Next Steps</h2> <p>What is great about doing a 1.0 release is that you know that there will be a 1.1 release, and a 1.2 release and a 2.0 release. <p>This is our way of saying "thank you for waiting" and giving our users a chance to start building applications, knowing that we have battle tested MonoMac and it is being used in our own products now <a href="#note">[1]</a>. <p>We obviously will continue improving the API, adding more frameworks as time goes by, but we will also be working with other communities to expand MonoDevelop's language support, create more templates for languages like F#, IronRuby, IronPython and UnityScript. <p>Although we have a great start for documentation, we hope that contributors will take advantage of a new web-based wiki and collaboration tool that we are building to improve the docs and help us make MonoMac's documentation the best. <p>Hopefully, we will also get more samples contributed to MonoMac and we will see a new wave of tutorials and we will see fascinating discussions on how to build better software while enjoying every second of it. <p><a name="note">[1]</a> (MonoDevelop 2.6 will be using MonoMac for its native dialog boxes). http://tirania.org/monomac/archive/2011/Mar-17.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Mar-17.html Thu, 17 Mar 2011 19:16:00 -0500 MonoMac hotfix <p><a href="https://github.com/hbons">Hylke Bons</a> warned us of a limitation in our MonoMac packager so we are issuing a new MonoMac refresh that fixes various bugs: <ul> <li>Supports using Mono.Posix.dll in packaged bundles. <li>Supports using System.Drawing in packaged bundles. <li>Fixes various BCL P/Invokes problems (we forgot to ship the config file :-) <li>No longer requires Mono 2.8.1, works with any mono 2.8+ </ul> <p>Follow the <a href="http://mono-project.com/MonoMac">standard instructions</a> to update your MonoMac add-in. <p>Hylke then got his <a href="https://github.com/hbons/SparkleShare/tree/master/SparkleShare/Mac/SparkleShare">native Mac client</a> for <a href="http://twitter.com/sparkleshare">SparkleShare</a> (a DropBox-like system, but backed up by Git or any Git hosting sit) working as a bundle on OSX. http://tirania.org/monomac/archive/2011/Feb-06.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Feb-06.html Sun, 06 Feb 2011 16:38:00 -0500 MonoMac Refresh! <P>We just pushed a new refresh of <a href="http://www.mono-project.com/MonoMac">MonoMac</a>. This release contains: <ul> <li>New complete bindings: QuartzComposer, CoreWlan, PdfKit, ImageKit and Addresbook. <li>AppKit: new classes: NSBezierPath, NSGradient; convenience methods for NSColor, NSTableView, NSMenuItem, and NSPasteboard. <li>CoreImage's CIVector and support in AppKit for CoreImage. <li>WebKit indexers and support for reporting user decisions. </ul> <p>In our shared core with MOnoTouch, these are the changes: <ul> <li>CoreGraphics: Support for transparency layers. <li>Foundation: API helpers to make NSIndexSet more pleasant to use; new methods to control the NSRunLoop; NSUrlProtocol and NSUrlProtocolClient classes. <li>ObjCRuntime: Exposed the shared library loading code and convenience methods to pull constants from shared libraries. <li>KeyChain: expose new methods for common operations (managing internet passwords) <li>CoreAnimation: bound a few missing constants. <li>OpenGL: new CAOpenGLLayer type. </ul> <p>Many new samples are now included with MonoTouch. Kenneth has contributed various ported samples from the CoreAnimation book exercising the API, fixing it, and providing many samples for developers to get started. We now ship 32 samples covering a wide range of Mac APIs. <p>Contributors to this release include: Geoff Norton, Alexander Shulgin, James Clancey, Maxi Combina, Regan Sarwas, Michael Hutchinson, Ashok Gelal and Miguel de Icaza. <p>Additionally, the first MonoMac app has hit the Mac AppStore! <p>Some small stats: MonoMac 0.4 was installed by 263 developers, MonoMac 0.5 by 369 developers, and MonoMac 0.6 (our last release) by 588. http://tirania.org/monomac/archive/2011/Feb-02.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Feb-02.html Wed, 02 Feb 2011 23:55:00 -0500 First MonoMac App Hits the Apple AppStore <p><a href="http://site.yvansoftware.be/">Yvan Janssens</a> (<a href="http://twitter.com/yvanjanssens">@yvanjanssens</a>) just wrote to let me know that <a href="http://itunes.apple.com/us/app/iproxify-plus/id409373452?mt=12">iProxify Plush</a>, his <a href="http://www.mono-project.com/MonoMac">MonoMac-powered</a> application, has been accepted for distribution on Apple's Mac AppStore. <p>This is an important development in the history of MonoMac, as someone has actually published a full executable based on the tools that we built (we have not tested this ourselves as we did not really have anything to publish). <p>It also means that we got all the details right to let people use C# to publish to the Mac AppStore: we do not take external dependencies, we bundle all of the Mono dependencies with the app and we follow all the relevant Apple rules for distribution. <p>Congratulations to Yvan for his published app! http://tirania.org/monomac/archive/2011/Jan-31.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Jan-31.html Mon, 31 Jan 2011 22:05:00 -0500 Patterns for Creating UITableViewCells <p>At one point or another, every UITableView programmer will outgrow the <a href="http://developer.apple.com/library/ios/#documentation/UserExperience/Conceptual/TableView_iPhone/TableViewCells/TableViewCells.html#//apple_ref/doc/uid/TP40007451-CH7">default set of UITableViewCells styles</a> available to them, and they will be forced to customize the cells to provide a better user experience. <p>The initial temptation of every lazy programmer like myself is to do the bare minimum amount of work to obtain the desired effect. This path typically starts by realizing that you can add a subview to your cell, like this: <pre class="code-csharp"> static UIImage logo = UIImage.FromFile ("logo.png"); UITableViewCell CreateCell () { var cell = new UITableViewCell (UITableViewCellStyle.Default, "key"); var imageView = new UIImageView (logo) { Frame = new RectangleF (10, 10, 20, 20); }; cell.ContentView.Add (imageView); return cell; } </pre> <p>Although the above code works, and you can get away with it for simple tasks, it does not take into consideration cell reuse. UITableViews like to recycle cells on the screen which is fine as long as you do not need to use a different image on each cell, as all of a sudden, you will need to keep track of the imageView value. <p>In other cases, your GetCell method will get bloated with a lot of inside information about all possible customizations that you might have done in a previous instance, and you will have to undo those. Apple's UICatalog sample is packed with code like that, and so is <a href="https://github.com/migueldeicaza/monotouch-samples/blob/master/monocatalog/textfield.cs#L62">my port</a> of the same code. <p>And that is just not a decent way of living. <p>You are miserable, your users are miserable and everyone around you is miserable. <p>My preferred pattern, which has worked better for me is to create a derived cell class that tracks all of my properties, and centralizes the management of updating the properties of my cell. <p>Assuming that my cell will render the contents of an object called "MyData", this is what my pattern looks like for custom UITableViewCells: <pre class="code-csharp"> // // I create a view that renders my data, as this allows me to reuse // the data rendering outside of a UITableViewCell context as well // public class MyDataView : UIView { MyData myData; public MyDataView (MyData myData) { Update (myData); } // Public method, that allows the code to externally update // what we are rendering. public void Update (MyData myData) { this.myData = myData; SetNeedsDisplay (); } } // // This is the actual UITableViewCell class // public class MyDataCell : UITableViewCell { MyDataView myDataView; public MyDataCell (MyData myData, NSString identKey) : base (UITableViewCellStyle.Default, identKey) { // Configure your cell here: selection style, colors, properties myDataView = new MyDataView (myData); ContentView.Add (myDataView); } public override void LayoutSubviews () { base.LayoutSubviews (); myDataView.Frame = ContentView.Bounds; myDataView.SetNeedsDisplay (); } // Called by our client code when we get new data. public void UpdateCell (MyData newData) { myDataView.Update (newData); } } </pre> <p>With the above pattern implemented, I can now add all of my view specific gadgetry into the MyDataView class, images, helper labels, or other views. <p>Then, the Update method needs to make sure that all of those extra views are updated when this method is invoked. All of the configuration for your cell needs to take place in this method, and nowhere else. <p>The client code that uses these views then looks like this: <pre class="code-csharp"> class MyTableViewDataSource : UITableViewDataSource { public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { MyData myData = Lookup (indexPath); var cell = tableView.DequeueReusableCell (key); if (cell == null) cell = new MyDataCell (myData); else cell.UpdateCell (myData); return cell; } </pre> <h3>The Extra UIView</h3> <p>You might be thinking that creating the extra UIView is not really worth the effort, as you likely only need to apply a few customizations, and you got already most of your bang for the buck by creating your custom UITableViewCell. <p>You would be right. <p>The reason for creating a custom UIView, is that there might come a time when you want to do some custom drawing in your cell. Perhaps add a nice gradient on the background, or perhaps draw some shadows, or mix large fonts with small fonts. <p>It might be just a couple of small touch-ups, nothing too complicated, but just a little extra polish. By using a custom UIView, you can now spice up your view just a tiny bit, by overriding the Draw method: <pre class="code-csharp"> public override void Draw (RectangleF rect) { var context = UIGraphics.GetCurrentContext (); UIColor.White.SetColor (); context.FillRect (Bounds); context.DrawLinearGradient (myGradient, start, end, 0); } </pre> <h3>Creating a MonoTouch.Dialog Element</h3> <p>If you are like me, lazy, you would likely not be writing a lot of GetCell methods and large dispatch tables for your UITableViews, and instead you are using <a href="https://github.com/migueldeicaza/MonoTouch.Dialog">MonoTouch.Dialog</a>. <p>MonoTouch.Dialog is an API that takes away the administrivia out of building UITableViews and lets you focus on the content. I <a href="http://tirania.org/blog/archive/2010/Feb-23.html">discussed MonoTouch.Dialog last year</a> on my old blog. <p>Once you have your own UITableViewCell, it is trivial to turn that into a MonoTouch.Dialog Element. You would do it like this: <pre class="code-csharp"> public class MyDataElement : Element { static NSString key = new NSString ("myDataElement"); public MyData MyData; public MyDataElement (MyData myData) : base (null) { MyData = myData; } public override UITableViewCell GetCell (UITableView tv) { var cell = tv.DequeueReusableCell (key) as MyDataCell; if (cell == null) cell = new MyDataCell (MyData, key); else cell.UpdateCell (MyData); return cell; } } </pre> <p>With the code above, you have everything you need to make your custom cell to be used with MonoTouch.Dialog. <p>You can see the entire pattern in action in <a href="https://github.com/migueldeicaza/TweetStation/blob/master/TweetStation/UI/TweetCell.cs">TweetStation's source code</a>. The 300 or so lines of code in that file are responsible for rendering a tweet in TweetStation. http://tirania.org/monomac/archive/2011/Jan-18.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Jan-18.html Tue, 18 Jan 2011 19:32:00 -0500 Mono Packager and the Apple AppStore <p>We are happy to announce the <a href="http://www.mono-project.com/MonoMacPackager">Mono Packager for OSX</a>. <center> <img src="http://mono-project.com/files/2/2a/Md-monomac-bundle.png"> <br> MonoDevelop UI for Mac Packages and Installers. </center> <p>The Mono Packager for OSX makes it possible to create self-contained Mono applications that will run on OSX without requiring the Mono.framework to be previously installed on the system. In combination with the <a href="http://www.mono-project.com/MonoMac">MonoMac project</a> you can build fully native MacOS X applications using your favorite .NET technologies. From your choice of Mono/.NET languages, to your choice of Mono/.NET library. <p>The packager can create both signed applications for distribution on the Mac AppStore, as well as creating installers for your software. <h3>Mono on the Mac: Some Background</h3> <p>Mono on OSX has historically been distributed as an image that installed itself in /Library/Frameworks/Mono.framework. Once Mono was installed, users could write code in C# or their favorite .NET/Mono language and run the resulting executable. <p>The problem is that Mono.framework contains an entire development stack: compilers, GUI tools, command line tools, libraries, documentation which is convenient for developers, but most of the time, not very useful for end-users. <p>This meant that developers would typically ask users to first install the Mono.framework (a big download) and then they could install their applications. <p>To work around that problem, some developers have chosen to manually embed Mono in their applications. This has always been possible, but it was error-prone as developers would have to manually assemble Mono into their application bundle, configure Mono properly, and initialize the Mono runtime themselves. Doable, but not pleasant. <p>With today's release, we have taken the burden of creating self-contained Mono applications out of developer's hands and added it as a standard feature for developers to use. <h3>The Mac AppStore</h3> <p>The Mac AppStore requires that applications submitted to it are completely self-contained and they do not depend on third-party frameworks to be installed on the system. It also requires that your application and installer be signed. <p>Both of those features are supported in our MonoMac Packager. Developers can now create Mac AppStore ready applications using MonoDevelop and MonoMac. We have integrated the package creation, installer creation, and signing processes into our MonoDevelop IDE. <p>All that developers have to do is sign up for Apple's Mac developer program, get their distribution certificates, build a fabulous application and upload the application using the Application Loader to Apple.com. <h3>Upcoming: Linking</h3> <p>In this version of the Mac bundler, we include all of the dependencies that your program takes. For example, if you use the System.Xml library, the entire System.Xml library will be bundled with the application. <p>In our next release, we will add support for <a href="http://www.mono-project.com/Linker">Mono's linker</a>, the same technology we used in <a href="http://monotouch.net">MonoTouch</a> to reduce the executable size. <p>When you choose to use use the linker, the granularity of distribute changes from the library-level to the type level. For example, if you only use one type from System.Xml, the linker will strip out all of the unused classes and generate a new System.Xml library that only contains the one type that you used. <p>We did not want to wait for the linker to be ready before shipping our packager, but we should have it ready soon. <h3>MonoMac Refresh</h3> <p>As part of this release we have also issued a refresh to the MonoMac library and templates. <p>From now on, MonoMac binaries will default to be 4.0 profile, allowing users to leverage all of the new features in the C# 4.0 language (like <tt>dynamic</tt>) as well as the new .NET 4.0 APIs that we introduced with Mono 2.8. <p>The updates to the MonoMac API are described in <a href="http://tirania.org/monomac/archive/2011/Jan-10-1.html">my other blog post</a>. http://tirania.org/monomac/archive/2011/Jan-10.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Jan-10.html Mon, 10 Jan 2011 17:23:00 -0500 New MonoMac Refresh! <p>As part of today's release of the <a href="http://tirania.org/monomac/archive/2011/Jan-10.html">Mono Packager for OSX</a> we have issued a new MonoMac refresh. <p>As we create more sample code, and start to write real applications with MonoMac, we have updated the API to be simpler, cleaner and more comprehensive. This release is all about small incremental improvements to the MonoMac API. <p>As usual, we have updated the our <a href="http://mono.ximian.com/monomac-docs/">MonoMac API documentation MonoMac API documentation</a>. If you are thinking about getting started with MonoMac, we strongly recommend you read our <a href="http://www.mono-project.com/MonoMac">MonoMac</a> page for some useful links and tutorials. <h3>Statistics</h3> <p>MonoMac 0.4 was installed by 263 developers, MonoMac 0.5 by 369 developers. Interesting considering that the holidays are a slow season: <center> <img src="http://tirania.org/shots/1101091106IHKGeOBC.png"> </center> <h3>Apps!</h3> <p><a href="http://twitter.com/#!/praeclarum">Frank Krueger</a> the creator of <a href="http://icircuitapp.com/">iCircuit</a> a real-time circuit emulator and editor for the iPad/iPhone has started a port of iCircuit to MacOS X using MonoMac: <center> <img src="http://tirania.org/shots/1101091942LfvK58IN.png"> </center> <p>Pretty amazing, considering that Frank only learned to use MonoMac yesterday (although he does have extensive MonoTouch experience). <b>Update:</b> He posted and <a href="http://yfrog.com/h8mx8p">updated screenshot</a> "now in technicolor". <h3>MacDoc Sample</h3> <p>During the holidays, I <a href="https://github.com/mono/monomac/tree/master/samples/macdoc">wrote MacDoc</a> a native front-end for the <a href="http://www.mono-project.com/Monodoc">MonoDoc documentation engine</a>. I also took Jonathan Pobst's <a href="https://github.com/jpobst/Kipunji">fabulous style sheets from Kipunji</a> to spice up the UI a little bit. <p>This is the result: <center> <img src="http://tirania.org/images/monomac-macdoc.png"> </center> <p>I still have to integrate the index and search features of MonoDoc into the UI, and I am struggling as to how to surface them in the UI. <p>The Index is supposed to have an alphabetical listing of classes, method, properties, fields, similar to the index at the end of a book. I always found this to be very useful when developing with .NET. The search functionality on the other hand uses Lucene to search in the documentation body. <p>At this point, I believe that I should add a tabbed widgets, and let the user pick between the tree view on the left and the index (with a new text-entry to do the incremental search). But if the users uses the search on the toolbar, I should replace the tree and the index with a list of results. <p>Does the above make sense, or you think it is a terrible UI idea and completely unacceptable for OSX users? <p>I thought about merging the index and the body search, but it would render the index search a bit useless. Anyways, if you are a Mac expert, please send feedback my way. http://tirania.org/monomac/archive/2011/Jan-10-1.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Jan-10-1.html Mon, 10 Jan 2011 16:01:00 -0500 CorePlot Bindings for MonoMac and MonoTouch <p>Happy New Year! <p>Today I wrote the MonoMac and MonoTouch bindings for the open source <a href="http://code.google.com/p/core-plot/">CorePlot</a> library. <p>The bindings are available from the <a href="https://github.com/mono/monotouch-bindings">binding collection module</a> on GitHub and binaries for both MonoTouch and MonoMac are available there. http://tirania.org/monomac/archive/2011/Jan-01.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2011/Jan-01.html Sun, 02 Jan 2011 00:39:00 -0500 MonoMac Happy Holidays Edition is out! <p>Just in time for your holidays, we have baked a new version of <a href="http://mono-project.com/MonoMac">MonoMac</a>. As usual, installation is very easy, just <a href="http://www.mono-project.com/MonoMac#Obtaining_MonoMac">follow these steps</a>. <p>As for some stats: 224 developers downloaded the MonoMac 0.4 add-in for MonoDevelop in the previous release, not bad at all! <center> <img src="http://tirania.org/shots/1012150251iPp5lcHM.png"> </center> <p>These are the changes since MonoMac 0.4 <ul> <li><a href="http://mono.ximian.com/monomac-docs/">API Documentation</a>! <ul> <li>Built on JPobst's <a href="https://github.com/jpobst/Kipunji">new documentation engine</a></li> <li>There are mostly automatically generated stubs now</li> </ul> </li> <li>New in CoreAnimation: <ul> <li>Layout managers</li> <li>Constrained layout manager</li> <li>CATextLayer can now set its font with the WeakFont property, or the SetFont () strong types.</li> </ul> </li> <li>CoreGraphics: <ul> <li>CGAffineTransform.Invert () method to obtain the inverse of an affine transformation</li> </ul> </li> <li>Foundation <ul> <li>NSObject.FromObject method automatically boxes .NET types into NSValue, NSString or NSNumber objects.</li> <li>Convenience function to create NSArrays from object [] arrays and using the new NSObject boxing functionality.</li> <li>New NSIndexSet convenience factory method and ToArray method</li> <li>NSDictionary and NSMutableDictionary have convenience methods that take object [] arrays, and do the boxing automatically (using the new NSArray functionality described above)</li> </ul> </li> <li>AppKit: <ul> <li>DoubleClick event on views that have support for double click actions (instead of using the DoubleAction selector + Target)</li> <li>NSTableView has a new Source property that can be used to blend both Delegate and the table view data source into one (NSTableViewSource which combines NSTableViewDataSource and NSTableViewDelegate)</li> <li>New: NSPredicate family of classes</li> <li>New: NSRuleEditor</li> </ul> </li> <li>AddressBook library: <ul> <li>We used to ship the source, but now it is included in the binary library.</li> </ul> </li> <li>CoreImage: <ul> <li>New in this release.</li> </ul> </li> <li>WebKit: <ul> <li>Many events that were previously only exposed as Objective-C style delegates are now proper C# events.</li> </ul> </li> <li>Engine: <ul> <li>Improved methods with return structures <li>Improved string [] marshalling <li>Now with INativeObject marshalling </ul> </li> </ul> <p>We have also updated the <a href="https://github.com/mono/monomac/tree/master/samples">samples</a> and added a few more. http://tirania.org/monomac/archive/2010/Dec-15.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2010/Dec-15.html Thu, 16 Dec 2010 00:35:00 -0500 The @" syntax in Objective-C vs C# <p>A common mistake that I see in some of the code from our customers, or from contributed samples to the MonoMac repository is the use of the @"string" syntax in C# programs. <b>Summary:</b> do not use the @"..." when porting Objective-C samples to C#. <h3>String Syntax in Objective-C and C#</h3> <p>Objective-C supports two kinds of string literals in your source code, strings that are surrounded by double-quotes and strings that are prefixed with the at-sign and then double quotes. <p>The first kind are zero-terminated C-style strings. For example the string "foo" is encoded by the compiler as the following four bytes: 'f', 'o', 'o' and zero plus the address of the string at the location where this is referenced. <p>The second kind, for example @"Hello World" is a CoreFoundation string, and the compiler has to encode by creating a static instance of a CoreFoundation CFString object: it has a class identifier, some object flags, a pointer to the data ('foo' in this case) and the length of the string. <p>In both the c-string style and the CFString style, escape sequences are processed by the compiler. This means that if you use "1\n2" or @"1\n2" this will produce in both cases a string consisting of the '1' character followed by a newline (byte value 10) and the '2' character. <p>In C# the syntax @"string" does not mean "encode as a CFString" object. Instead it is a<a href="http://msdn.microsoft.com/en-us/library/362314fe(v=vs.71).aspx"> quoted-string literal</a>, and it instructs the compiler to avoid performing escape sequence processing. In C# the strings "1\n2" and @"1\n2" have respectively lengths 3 and 4. The former one consists of the characters '1', newline (byte value 10) and character '2'. While the latter consists of the characters '1', '\', 'n' and '2'. <h3>System.String vs Foundation.NSString in MonoMac/MonoTouch</h3> <p>In the MonoTouch/MonoMac binding strings are almost always exposed in the binding with the native C# string type (System.String). Any conversions between the C# string and the Objective-C string type are done by the runtime. <p>There are a handful of places where we must expose NSString values instead of strings. This is usually necessary when the underlying Objective-C code performs reference comparisons instead of content comparisons for strings. Some Objective-C APIs for example use these strings as special "tokens" that you must pass verbatim in your application to a method. <p>We typically use those for notification names, keys in dictionaries and a handful of other places. You will notice in those handful of cases that Mono's API's expose an NSString parameter or return value instead of a string parameter or return value. <p>For example if you have a AddNotification (NSString key) API, you would typically use it like this: <pre class="code-csharp"> // example class exposing a notificatin as an NSString: // class SomeClass { // NSString WakeUpNotification { get; } // } AddNotification (SomeClass.WakeUpNotification); </pre> <h3>Conversions</h3> <p>Converting from a C# string to an NSString is easy, all you have to do is call new NSString ("mystring"). <p>To go the other way around from an NSString to a string, you can either use an explicit cast (this is the recommended design pattern from the <a href="http://www.amazon.com/gp/product/0321545613?ie=UTF8&amp;tag=tiraniaorg-20&amp;linkCode=as2&amp;camp=1789&amp;creative=390957&amp;creativeASIN=0321545613">Framework Design Guidelines</a>) or you can use the ToString () method on an NSString. http://tirania.org/monomac/archive/2010/Dec-14.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2010/Dec-14.html Wed, 15 Dec 2010 00:33:00 -0500 NSNumbers, NSValues, Dictionaries and Arrays <p>A couple of days ago, <a href="http://jacksonh.tumblr.com/">Jackson</a> pointed out that one of the samples in this blog could be further simplified if we took advantage of C#'s params arguments. The sample in question was this code snippet from QTRecorder, used to return an NSSet: <pre class="code-csharp"> [Export] public static NSSet keyPathsForValuesAffectingHasRecordingDevice () { return new NSSet (new string [] {"SelectedVideoDevice", "SelectedAudioDevice"}); } </pre> <p>In the above example, we have to manually construct the string array, so that we can call the NSSet (string [] args) constructor. Jackson correctly pointed out that the above could be simplified if we introduced an NSSet (params string [] args) constructor. This lets the compiler do the work for us, so the sample above can be written like this instead: <pre class="code-csharp"> [Export] public static NSSet keyPathsForValuesAffectingHasRecordingDevice () { return new NSSet ("SelectedVideoDevice", "SelectedAudioDevice"); } </pre> <p>This got me thinking about another possible improvement to the API. In a number of places in the MonoMac/MonoTouch API it is necessary to pass numbers, strings, booleans, points, rectangles, affine transforms and 3D transforms in NSDictionary and NSArray objects. <p>Since Objective-C does not have language-assisted auto-boxing like C# does, programmers have to manually box those in either NSValue types or NSNumber types. An NSNumber can contain booleans, 16, 32 and 64 bit integers and unsigned integers as well as floats and doubles. NSValues are typically used to box points, rectangles, sizes and 2D and 3D affine transformations. <p>In a few of the current samples we have code like this: <pre class="code-csharp"> var objects = new NSObject [] {&nbsp; new NSNumber (13), new NSNumber ((float) 0.5) }; var keys = new NSObject [] { new NSString ("speed"), new NSString ("volume") }; var dict = NSDictionary.FromObjectsAndKeys (objects, keys); </pre> <p>The above clearly is too verbose for no good reason. We have now introduced methods that take general purpose object [] arrays, containing regular C# data types and will do the automatic boxing: <pre class="code-csharp"> var objects = new NSObject [] {&nbsp;13, 0.5 }; var keys = new NSObject [] {&nbsp;"speed", "volume" }; var dict = NSDictionary.FromObjectsAndKeys (objects, keys); </pre> <p>The method that does the object to NSObject conversion is a convenience static method in the NSObject class, with the following signature: <pre class="code-csharp"> public static NSObject FromObject (object obj); </pre> <p>The function can be used to convert nulls, booleans, numbers, strings, IntPtrs, SizeF, RectangleF, PointF on both MonoMac and MonoTouch and in MonoTouch it additionally supports CGAffineTransform, CATransform3D and UIEdgeInsets. http://tirania.org/monomac/archive/2010/Dec-09.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2010/Dec-09.html Fri, 10 Dec 2010 00:33:00 -0500 Using Key-Value Coding with MonoMac <p><a href="http://monomac.files.wordpress.com/2010/12/db-12.png"><img class="alignright size-full wp-image-32" title="db-1" src="http://monomac.files.wordpress.com/2010/12/db-12.png" alt="" width="192" height="381" /></a><a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueCoding/Concepts/Overview.html">Key-Value Coding</a> is a set of practices that allow applications to access object properties using strings. This is similar to <a href="http://msdn.microsoft.com/en-us/library/cc189022(VS.95).aspx">Binding Expressions</a> in Silverlight. In both cases the purpose is to allow tooling that does not directly have access to your native code to access properties from your program. <p>You would typically use this from a tool like Interface Builder, where you can use the Binding Inspector (⌘4 from Interface Builder) to explore the possible values of the component that you can data bind. In Interface Builder you would use string to describe the name of the property that you want to access. For example, consider the options available for the NSPopUpButton component show on the right. All of those properties of the NSPopUpButton can be pulled directly from your code from Interface Builder without having to manually hook things up. <p>To use this with MonoMac, all you have to do is make sure that any property that you want to access from Interface Builder is flagged with the [Export] attribute. If you apply the Export attribute without any parameters, it will expose the C# name of your property for Key-Value access. You can change the name that is exposed by passing a parameter, for example: [Export ("myIndex")]. <p>The <a href="https://github.com/mono/monomac/tree/master/samples/QTRecorder">QTRecorder sample</a> shows how various elements in the UI are connected to the code: [caption id="attachment_38" align="alignnone" width="583" caption="MonoMac port of QTRecorder sample"]<a href="http://monomac.files.wordpress.com/2010/12/qtrecorder2.png"><img class="size-full wp-image-38" title="qtrecorder2" src="http://monomac.files.wordpress.com/2010/12/qtrecorder2.png" alt="" width="583" height="547" /></a>[/caption] <p><a href="http://monomac.files.wordpress.com/2010/12/props.png"><img class="alignleft size-medium wp-image-36" title="props" src="http://monomac.files.wordpress.com/2010/12/props.png?w=169" alt="" width="169" height="300" /></a>In that sample, the class QTRecorder, a class derived from NSDocument exposes properties that are hooked up directly to the Enabled properties in various buttons in the UI and properties to populate and control the contents of the various popups in the application. All of these bindings are configured by setting the target of the binding to be the "File's Owner", in this case the QTRecorder class, as it happens to load the QTRecorder.nib file. You can see the complete list of bindings in the screenshot on the left. <p>Let us explore what happens in the application. The Video Devices popup is controlled through three bindings: the Content, the Content Values and the Selected Object. This is what the binding are configured to in Interface Builder for all three properties: <p><a href="http://monomac.files.wordpress.com/2010/12/binding2.png"><img class="alignnone size-full wp-image-41" title="binding" src="http://monomac.files.wordpress.com/2010/12/binding2.png" alt="" width="640" height="105" /></a> <p>The <strong>Content</strong> is bound to the VideoDevices property in the source code, this is a property that merely returns the strongly typed QTCaptureDevice array of the available devices. The <strong>Content Values </strong>is bound to the VideoDevices.localizedDisplayName. The first part of the key matches our VideDevices array, and the second part of the key happens to be the Objective-C name of a property exposed by the QTCaptureDevice that provides the name of the device to display. The actual item selected on the screen is controlled by the <strong>Selected Object</strong> binding. In this case, a new property, the SelectedVideoDevice property. At this point, the NSPopUpButton will populate its contents using these bindings. Additionally, when the user selects a different item, the property bound to the Selected Object will be invoked with the new value. Our code responds by configuring the QTCaptureSession accordingly. <p>Another interesting binding takes place with the recording button. The recording button hasits Enabled property bound to the HasRecordingDevice C# property and has its Value bound to the C# Recording property. When we change the video source in the popup, the button responds by either getting grayed out or becoming active. Although this could have been done programmatically in response to the new value set in the SelectedVideoDevice property, the code takes advantage of the built-in notification system and instead reacts to changes to the SelectedVideoDevice automatically. <p>This is done by using the <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/KeyValueObserving/Concepts/DependentKeys.html">dependency keys feature</a> a feature of Key-Value Coding. It requires that the code exports a specially-named method which is prefixed with the string "keyPathsForValuesAffecting". These methods are are meant to return an NSSet containing the names of the properties that depend on that particular property. In our case this is: <pre class="code-csharp">[Export] public static NSSet keyPathsForValuesAffectingHasRecordingDevice () { return new NSSet ("SelectedVideoDevice", "SelectedAudioDevice"); }</pre> <p>Once that is done, the runtime knows that when either one of the SelectedVideoDevice or SelectedAudioDevice change, it has to query the value for HasRecordingDevice again. http://tirania.org/monomac/archive/2010/Dec-07.html miguel@gnome.org (Miguel de Icaza) http://tirania.org/monomac/archive/2010/Dec-07.html Wed, 08 Dec 2010 00:33:00 -0500