Rx-friendly NSNotificationCenter usage on Xamarin.iOS

During the course of building an iOS app, at some point you're likely to need to hook into the NSNotificationCenter functionality. Not to be confused with the consumer-side Notification Center in iOS, it provides a pub/sub-like mechanism that you can use to be subscribed to notifications posted by the OS (typically) in response to various system and application events. For example, you can observe the UIKeyboardWillChangeFrameNotification, which is posted before the changes to the soft keyboard size and position are applied (e.g. being displayed or hidden, or when adjusting to a new orientation), in order to reposition important parts of your UI to ensure they remain unobscured. As the notification center typically outlives objects interested in a notification (e.g. a ViewController, which is disposed after being popped off the navigation stack), observers should be removed when no longer needed.

If you're familiar with .NET, you've probably noticed some similarities between the Notification Center semantics and some of the Reactive Extensions (Rx) semantics. Rx-oriented applications - like those written using ReactiveUI - are already 'aware' of disposal semantics and it would be nice to be able to work notification center subscription/unsubscription into the existing mechanisms. Additionally, having Rx powers over notifications - essentially streams of values over time - is also highly desirable. Fortunately, it's trivial to wrap the notification center observation to get Rx semantics, using an extension method like this:

Now you can subscribe to NSNotificationCenter with Rx powers! For example:

    .Select(n => n.UserInfo[UIKeyboard.FrameEndUserInfoKey])

Disposing the IDisposable returned by ObserverNotification will remove the appropriate NSObserver from the notification center. Not having to deal with the NSObserver yourself helps remove some of the impedence mismatch between iOS and .NET, which is always welcome. Of course, as an added bonus you can use other Rx operators like CombineLatest, Throttle, Delay etc. now too. Enjoy!