July 22, 2014 4:38 GMT

Having Fun With UIVisualEffectViews in iOS 8 & Xamarin

As you have probable seen by now, UIVisualEffectView in iOS 8 gives us an easy way to apply a blur or vibrancy effect to UI elements. While alone this effect is pretty cool, I wanted to see what we could do if we had a bit of fun with it.

Blurred MapView

The concept here is to force the focus on the location you wish the user to be looking. To do this we blur out the entire map but leave a circular transparent section in the centre. To do this we set up our view like this:


private UIVisualEffectView blurView;
private const int CIRCLE_RECT_SIZE = 250;

public override void ViewDidLoad ()
{
   base.ViewDidLoad ();
			
   this.blurView = new UIVisualEffectView (UIBlurEffect.FromStyle (UIBlurEffectStyle.Light));
   this.blurView.Frame = this.View.Frame;
   //Allows the map underneath to be interacted with
   this.blurView.UserInteractionEnabled = false;
   this.View.Add (this.blurView);

   //Create a masking layer to cut out a section of the blur
   var maskLayer = new CAShapeLayer ();
   var maskPath = new CGPath ();
   maskPath.AddRect (this.blurView.Bounds);
   maskPath.AddEllipseInRect (new RectangleF (((this.blurView.Bounds.Width - CIRCLE_RECT_SIZE) / 2),   ((this.blurView.Bounds.Height - CIRCLE_RECT_SIZE) / 2), CIRCLE_RECT_SIZE, CIRCLE_RECT_SIZE));
   maskLayer.Path = maskPath;
   maskLayer.FillRule = CAShapeLayer.FillRuleEvenOdd;
   this.blurView.Layer.Mask = maskLayer;
}

Effect Button

Following on with the circle theme, here is a button which contains a UIEffectView clipped to a circle. This gives it an interesting look different from a usual UIButton.


public CircularEffectButton (PointF location, float size, UIVisualEffect effect, UIColor backgroundColor, string title, UIColor titleColor)
: base(UIButtonType.Custom)
{
   this.Frame = new RectangleF(location, new SizeF(size, size));
   this.effectView = new UIVisualEffectView (effect);
   this.effectView.Frame = new RectangleF(new PointF(0,0), this.Frame.Size);
   
   //Allows for the button to be tappable
   this.effectView.UserInteractionEnabled = false;
   this.Add (this.effectView);
   
   //Set a background color with a small Alpha (gives a hint of color)
   this.BackgroundColor = backgroundColor.ColorWithAlpha(0.2f);
   this.SetTitle (title, UIControlState.Normal);
   
   //Get a color which contrast the background for the title text
   var contrastingColor = this.ContrasingColor (backgroundColor);
   this.SetTitleColor (contrastingColor, UIControlState.Normal);
   this.TitleLabel.AdjustsFontSizeToFitWidth = true;
   this.TitleLabel.TextAlignment = UITextAlignment.Center;
   this.Layer.CornerRadius = size / 2;
   this.Layer.BorderWidth = 1;
   this.Layer.BorderColor = contrastingColor.CGColor;
   this.ClipsToBounds = true;
}

Bringing this all together gives us something like this!



Obviously this amount of dynamic effects takes a significant amount of processing power. Always remember “WITH GREAT POWER THERE MUST ALSO COME–GREAT RESPONSIBILITY!”

Get the sample on GitHub here.


July 21, 2014 6:00 GMT

Live Webinar: Test Apps on Hundreds of Devices with Xamarin Test Cloud

Xamarin Test Cloud

There are hundreds of mobile devices, OS versions, form factors and screen resolutions in use today, and your app needs to run on all of them. Xamarin Test Cloud makes it fast and easy to test your mobile apps on hundreds of real iOS and Android devices in the cloud, automatically.

Join Chris King, Xamarin’s Sr. Customer Success Engineer, for a live webinar this Thursday, July 24th at 8am PDT/ 11am EDT to find out why Xamarin Test Cloud is the easiest and fastest way to automate UI testing to ensure that you find bugs before your users do.

All registrants will receive a copy of the webinar, so please feel free to register even if you can’t attend.

Register Here

Want to get a head-start for the webinar? Take a few minutes to learn more about Xamarin Test Cloud.

July 17, 2014 5:52 GMT

Using Custom Controls in Xamarin.Forms on Windows Phone

Xamarin.Forms lets developers create native user interfaces on iOS, Android and Windows Phone from a single, shared C# codebase. Since the UI is rendered using the native controls of the target platform, it gives you great flexibility in customizing the controls separately on each platform. Each control is rendered differently on each platform using a Renderer class, which in turn creates a native control, arranges it on the screen and adds the behavior specified in the shared code.

Previously, we showed you how to build custom renderers in Xamarin.Forms on iOS and Android platforms to extend custom built controls. In case you missed it, its all here:

In practice,  you will use the same techniques to create custom renderers on Windows Phone as well.

WP-CustomControls-Xamarin.Forms

Windows Phone Custom Controls

.NET third party vendors provide you with wide range of top quality reusable UI controls on the Windows Phone platform. Sometimes it is easier to buy and use them than to build something on your own. Especially, the data visualization controls such as charts that transform your tabular data into something beautiful on the Windows Phone screen.

In this blog post, I will take you through steps involved in integrating a Infragistics XamDataChart control for Windows Phone in Xamarin.Forms. Xamarin.Forms-CustomControl-Charts

There are two main parts to implementing a custom control with a renderer -

  1. Create your own custom Xamarin.Forms control with bindable properties in Shared Project so that Xamarin.Forms API can refer them.
  2. Create a renderer in Windows Phone platform that will be used to display the Infragistics XamDataChart control and subscribe to property changed notifications

CustomChartView Control

In my shared project, I’m going to create a new control called CustomChartView that will be used in my Xamarin.Forms page. CustomChartView must inherit from Xamarin.Forms.View.

public class CustomChartView : View
{
  public static readonly BindableProperty ItemSourceProperty =
    BindableProperty.Create<CustomChartView, StockMarketDataSample>(p =>
    p.ItemSource, new StockMarketDataSample());
  public StockMarketDataSample ItemSource
  {
    get { return (StockMarketDataSample)GetValue(ItemSourceProperty); }
    set { SetValue(ItemSourceProperty, value); }
  }
  // Additional bindable properties
}

Notice the BindableProperty called ItemSourceProperty - this property is my DataModel which is of type StockMarketDataSample that has some necessary logic to simulate live data. In a real scenario, this will be replaced with the data that comes from a web service or something similar. In the code, you will see two more properties PriceDisplayType and ShowSpline. These are the properties that will help us interact with the chart for e.g. for changing the Price Type (CandleStick or OHLC) or Show/Hide a SplineAreaSeries from Xamarin.Forms controls.

CustomChartView Renderer

Now, with my Xamarin.Forms control in place I can write some Windows Phone platform specific code. I will implement a CustomChartViewRenderer class that inherits from a ViewRenderer and layout the XamDataChart on it.

public class CustomChartViewRenderer : ViewRenderer<CustomChartView, XamDataChart>
{
  XamDataChart DataChart;
  public CustomChartViewRenderer()
  {
    DataChart = new XamDataChart();
    //..code
  }
  //.. code
}

Since this renderer on Windows Phone inherits from View, which means Xamarin.Forms will handle all of the size calculations and will have the normal properties of a standard Windows Phone View. Add the XamDataChart to the project and update the references accordingly. Additionally, you will need to add more code to set your XAxis, YAxis and the FinancialPriceSeries to the XamDataChart. That code has been omitted from this post for brevity.

Now, I will set my renderer to display the XamDataChart control when the CustomChartView is added to the page layout. This is done by overriding the OnElmentChanged method and calling the SetNativeControl method in it.

protected override void OnElementChanged(ElementChangedEventArgs<CustomChartView> e)
{
  base.OnElementChanged(e);
  if (e.OldElement != null || this.Element == null)
    return;
  UpdateChart();
  SetNativeControl(DataChart);
}

UpdateChart() method is a private method that sets the DataContext of the XamDataChart control to the Xamarin.Forms CustomChart control’s ItemSource property.

private void UpdateChart()
{
  DataChart.DataContext = this.Element.ItemSource;
  DateXAxis.ItemsSource = this.Element.ItemSource;
  series.ItemsSource = this.Element.ItemSource;
  //.. code
}

Export Renderer Attribute

[assembly: ExportRenderer((typeof(CustomChartView)), typeof(CustomChart.WinPhone.ViewRenderers.CustomChartViewRenderer))]
namespace CustomChart.WinPhone.ViewRenderers
{
  public class CustomChartViewRenderer : ViewRenderer<CustomChartView, XamDataChart>
  {
  }
}

To get the control to show up in the actual view, I need to set an attribute ExportRenderer to the CustomChartViewRenderer class.

Wiring up the UI in XAML

Finally, I will add our custom control to the Page.  There are two approaches to create user interfaces in Xamarin.Forms. The first one is to create UI views entirely with source code using the Xamarin.Forms API. The other option available is to use Extensible Application Markup Language (XAML) which is the approach I’ve taken to build this demo.

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
			 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
		     x:Class="CustomChart.HomePage"
             xmlns:custom="clr-namespace:CustomChart.CustomControls;assembly=CustomChart.WinPhone">
    <Grid HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" >
        <Grid.RowDefinitions>
            <RowDefinition Height="80"/>
            <RowDefinition Height="80"/>
            <RowDefinition Height="*" />
            <RowDefinition Height="1" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="1"/>
        </Grid.ColumnDefinitions>
        <Grid.Padding>20</Grid.Padding>
        <StackLayout Orientation="Horizontal" Grid.Row="0" Grid.Column="0" HorizontalOptions="Center">
            <Button Text="Start" x:Name="StartButton" />
            <Button Text="Stop"  x:Name="StopButton"  />
            <Label Text="Spline:" VerticalOptions="Center"/>
            <Switch x:Name="ShowSplineSwitch"/>
        </StackLayout>
        <Picker x:Name="chartPicker" Title="Chart Type" HorizontalOptions="FillAndExpand" VerticalOptions="Center" Grid.Row="1"/>
        <custom:CustomChartView x:Name="chart" Grid.Row="2" />
    </Grid>
</ContentPage>

This page contains a Start Button – that starts a live feed, a Stop Button – thats stops the live feed, a Switch – that lets you show/hide a SplineAreaSeries in the Chart, and a Picker – that let’s you choose the Price Display Type (CandleStick or OHLC).

Xamarin.Forms-CustomControl-Charts-Spline

Handling Property Changes 

In the CustomChartControl of the shared project, along with the ItemSourceProperty, I have exposed the PriceDisplayTypeProperty and ShowSplineProperty as well. We can now easily set these property to interact with the XamDataChart. To make this work, we need to listen to the property changed event and set appropriate property of the XamDataChart. We will override the OnElementPropertyChanged method in the CustomChartViewRenderer class to do so.

protected override void OnElementPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
  base.OnElementPropertyChanged(sender, e);
  if (Control == null || Element == null)
    return;
  if (e.PropertyName == CustomChart.CustomControls.CustomChartView.PriceDisplayTypeProperty.PropertyName)
    series.DisplayType = Element.PriceDisplayType.ToIGPriceType();
  if (e.PropertyName == CustomChart.CustomControls.CustomChartView.ShowSplineProperty.PropertyName)
    ShowHideSpline();
}
private void ShowHideSpline()
{
  if (this.Element.ShowSpline)
    DataChart.Series.Add(splineSeries);
  else if (DataChart.Series.Contains(splineSeries))
    DataChart.Series.Remove(splineSeries);
}

Bringing it all together

That’s it! Now we can set these properties in the appropriate event handlers of the controls. Also, setting the ItemSource property to a StockMarketDataSample will populate the chart with the values.

public HomePage ()
{
  InitializeComponent ();
  chart.ItemSource = _data = new StockMarketDataSample();
}
void ShowSplineSwitch_Toggled(object sender, Xamarin.Forms.ToggledEventArgs e)
{
  chart.ShowSpline = e.Value;
}
void chartPicker_SelectedIndexChanged(object sender, EventArgs e)
{
  PriceDisplayType priceDisplayType;
  if (Enum.TryParse<PriceDisplayType>(chartPicker.Items[chartPicker.SelectedIndex], out priceDisplayType))
    chart.PriceDisplayType = priceDisplayType;
}

To simulate a Live Data, StockMarketServiceClient is used which has a timer that ticks every few milliseconds and raises an event with new value. Subscribing to that event and updating the ItemSource will change the visualization in the chart.

Xamarin.Forms-CustomControl-WPTo learn more about customizing your Xamarin.Forms controls and applications be sure to read our documentation.

Infragistics controls were used as an example in this post to show you how well Xamarin.Forms can integrate with third party controls. You can use any third party controls or custom controls that you have built with Xamarin.Forms and the procedure to get that working remains the same. 

Source Code

You can download the full source code for this project from my GitHub. Make sure you download and install Infragistics libraries before compiling.

Discuss this blog post in the Xamarin Forums

July 17, 2014 5:47 GMT

Mocast

image

For the past couple months, I have been working on a top secret project that aims to redefine the way work will get done, address key industry mobility challenges and spark true mobile-led business change. I’m just kidding, it’s a podcast player!

Why?

Mocast is not going to redefine how work gets done, but I am hoping it redefines how you listen to podcasts.

I wrote Mocast because I was unhappy with the iOS podcast app selection. While there are almost as many iPhone podcast players as there are weather apps, I find that they all have two fatal flaws.

First, they take downloads way too seriously. Most UIs differentiate downloaded vs. not downloaded episodes and bifurcate their interface along those lines. This is silly to us podcastistas who aren’t the greatest at planning ahead.

Second, they take new episodes too seriously. Whole apps seem built with only new episodes in mind as they hide away the back catalog. I don’t know why this is. My favorite podcast, The Incomparable has an amazingly rich back catalog of episodes that I love to listen to. It’s nice when a new episode arrives but there’s no need over-emphasize them at the cost of the full catalog.

How?

First, and most importantly, downloads are completely optional when using Mocast. You can always play an episode immediately, whether you have downloaded it or not thanks to streaming.

Next, it’s a single-screen thumb-based UI. You see, I walk a lot in parks and can’t stand apps that have a complex navigation history with back buttons with crazy nesting - I need to be able to do everything with my thumb and I need the screen to be predictable. Mocast makes that possible. You will only ever see a list of episodes, a search box, and play controls. There is no Now Playing screen, no episode screens, just episodes and a big play button. I even tried to limit the number of buttons all together. This is a slide-happy, thumb loving app.

Mocast puts you in control with queues. Mocast presents four different lists of episodes: Per-podcast, New, Queued, and History. While Mocast manages most of those lists, The Queue is fully under your control. You can add episodes to listen to later or setup a nice set of old favorites to listen to when nothing new is coming in.

Mocast acknowledges and embraces our busy lives that prevent us from completing episodes. It keeps a running History of past played episodes (and of course where you left off) so that you can jump around between episodes without ever worrying about forgetting to finish one.

Lastly, and this is one of my favorite features, Mocast lets you perform offline full-text searches of all episodes’ show notes. Do you want to see all podcasts that mentioned WWDC 2014? Easy. How about all Star Wars episodes? Done. Every list Mocast shows is searchable and the search box is always ready for you at the top of the app.

A bit of fun

While I truly believe Mocast has a lot to offer in terms of usability, I think it’s a fun app too. Here are a few of my favorite features.

Siri is used to announce episodes. Yes, that Siri. It took some string pulling and I have to deal with a 150 page rider, but she’s there to let you know what you’re listening to.

The time scrubber is thumb friendly, velocity controlled, big and bold. I can’t stand apps with tiny scrubbers so I hope you will enjoy this one.

Dark disco theme that adapts to your episodes. Mocast is just a sad dark gray app until you start adding podcasts. But once they’re in, it lights up with their colors and keeps those colors moving around. It’s hard to describe in words, so I hope you’ll risk the $3 to see for yourself.

There are more features than this tucked away! I hope you’ll check them out!

Colophon

As with all my apps, I wrote Mocast in C# using Xamarin.iOS. She came out to be about 8,000 loc with about 60% of that code lying in the UI layer.

July 17, 2014 2:31 GMT

Custom Modal Transitions in iOS 8 & Xamarin

With the advent of iOS 8 and the inclusion of the UIPresentationController we now have a free reign in terms of presenting and transitioning to modal views in iOS.

To create a custom modal transition we are required to use 3 classes:

  • UIPresentationController
  • UIViewControllerAnimatedTransitioning
  • UIViewControllerAnimatedTransitioningDelegate

Apart from the excessively long names, these classes are really easy to use and setting up your awesome modal presentation transition will be a doddle.

UIPresentationController

This class is responsible for being the container of the view being presented, in my example we create a dimmed view to overlay the view being transitioned from. The required overriden methods / properties are:

  • FrameOfPresentedViewInContainerView: returns a frame which the presented view will be displayed in.
  • PresentationTransitionWillBegin: apply any visual configuration / animations to the container view before the presenting transition.
  • DissmissalTransitionWillBegin: apply any visual configuration / animations to the container view before the dismissing transition.
public override RectangleF FrameOfPresentedViewInContainerView {
   get {
           var containerBounds = this.ContainerView.Bounds;

           var presentedViewFrame = RectangleF.Empty;
           presentedViewFrame.Size = new SizeF (300, 300);
           presentedViewFrame.X = (containerBounds.Width / 2) - (presentedViewFrame.Width / 2);
           presentedViewFrame.Y = (containerBounds.Height / 2) - (presentedViewFrame.Height / 2);

           this.PresentedView.Layer.CornerRadius = presentedViewFrame.Size.Width / 2;
           this.PresentedView.ClipsToBounds = true;

           return presentedViewFrame;
	}
}

public override void PresentationTransitionWillBegin ()
{
   this.dimmingView.Frame = this.ContainerView.Bounds;
   this.dimmingView.Alpha = 0;

   this.ContainerView.InsertSubview (this.dimmingView, 0);
   var coordinator = this.PresentedViewController.GetTransitionCoordinator ();
   if (coordinator != null) {
      coordinator.AnimateAlongsideTransition((context) => 
      {
         this.dimmingView.Alpha = 1;
      }, 
      (context) => 
      {});
   } else {
      this.dimmingView.Alpha = 1;
   }
}

public override void DismissalTransitionWillBegin ()
{
   var coordinator = this.PresentedViewController.GetTransitionCoordinator ();
   if (coordinator != null) {
      coordinator.AnimateAlongsideTransition((context) => 
      {
         this.dimmingView.Alpha = 0;
      }, 
      (context) => {});
   } else {
      this.dimmingView.Alpha = 0;
   }
}

UIViewControllerAnimatedTransitioning

The main animation to display the presented view is handled here, there are only two required methods to override:

  • TransitionDuration: returns (as per the name) the duration of the transition based on the transitioning context.
  • AnimateTransition: create you animation transition between your two view controllers here.
public override double TransitionDuration (IUIViewControllerContextTransitioning transitionContext)
{
   return 0.5;
}

public override void AnimateTransition (IUIViewControllerContextTransitioning transitionContext)
{
   var fromVC = transitionContext.GetViewControllerForKey (UITransitionContext.FromViewControllerKey);
   var fromView = fromVC.View;
   var toVC = transitionContext.GetViewControllerForKey (UITransitionContext.ToViewControllerKey);
   var toView = toVC.View;
   var containerView = transitionContext.ContainerView;

   var isPresentation = this.IsPresentation;

   if (isPresentation) {
      containerView.AddSubview (toView);
   }

   var animatingVC = isPresentation ? toVC : fromVC;
   var animatingView = animatingVC.View;

   var appearedFrame = transitionContext.GetFinalFrameForViewController (animatingVC);
   var dismissedFrame = this.startFrame;

   var initialFrame = isPresentation ? dismissedFrame : appearedFrame;
   var finalFrame = isPresentation ? appearedFrame : dismissedFrame;
   animatingView.Frame = initialFrame;

   UIView.AnimateNotify (0.5f, 
      0, 
      300.0f, 
      5.0f, 
      UIViewAnimationOptions.AllowUserInteraction | UIViewAnimationOptions.BeginFromCurrentState,
      () => { animatingView.Frame = finalFrame;	},  
      new UICompletionHandler((bool finished) => 
      {
         if(!isPresentation){
            fromView.RemoveFromSuperview();
         }
         transitionContext.CompleteTransition(true);
      }));
}

UIViewControllerAnimatedTransitioningDelegate

The glue that holds all of this awesomeness together, responsible for creating the UIPresentationController and marshalling the UIViewControllerAnimatedTransitioning instances for dismissal and presentation.

public override UIPresentationController GetPresentationControllerForPresentedViewController (UIViewController presentedViewController, UIViewController presentingViewController, UIViewController sourceViewController)
{
   if (this.awesomePresentationController == null) {
      this.awesomePresentationController = new AwesomePresentationController (presentedViewController, presentedViewController);
   }
   return this.awesomePresentationController;
}
			
public override IUIViewControllerAnimatedTransitioning GetAnimationControllerForDismissedController (MonoTouch.UIKit.UIViewController dismissed)
{
   var transitioning = this.AnimationTransitioning;
   transitioning.IsPresentation = false;
   return transitioning;
}

public override IUIViewControllerAnimatedTransitioning PresentingController (UIViewController presented, UIViewController presenting, UIViewController source)
{
   var transitioning = this.AnimationTransitioning;
   transitioning.IsPresentation = true;
   return transitioning;
}

Implementing The Presentation

this is done in a few lines of code as follows:


partial void TransitionPressed (MonoTouch.Foundation.NSObject sender)
{
   var overlayVC = (OverlayViewController)this.Storyboard.InstantiateViewController("OverlayVC");

   this.transitioningDelegate = new AwesomeTransitioningDelegate (((UIButton)sender).Frame);

   overlayVC.ModalPresentationStyle = UIModalPresentationStyle.Custom;
   overlayVC.TransitioningDelegate = this.transitioningDelegate;

   this.PresentViewControllerAsync(overlayVC, true);
}

Get the sample on GitHub here.


July 16, 2014 5:33 GMT

New Collection View Features in iOS 8

Collection Views are a powerful user interface technology for laying out collections of data. With fantastic support for high performance grid layouts, flexible line based layouts, and fully custom layouts, along with integrated animation capabilities, they make creating beautiful data-driven UIs a wonderful experience both for the developer and the end user.

collection views

iOS 8 adds some nice enhancements to Collection Views, including the ability to self-size cells without the need for using a delegate. Likewise, the layout attributes of individual cells can now be adjusted directly from within the cell class without having to use a delegate. This makes it easier to make small layout changes that are related to a particular cell.

Self-sizing Cells

First, let’s look at how to self-size cells. Before iOS 8, creating cells that sized to their content required working within a layout class directly or via a layout’s delegate, such as the UICollectionViewDelegateFlowLayout.

For example, the following code adjusts the cell size to fit cells comprised of simple UILabels, presented using a UICollectionViewFlowLayout:

class FlowLayoutDelegate : UICollectionViewDelegateFlowLayout
{
  string[] items;
  UIStringAttributes attr;
  public FlowLayoutDelegate (string[] items)
  {
    this.items = items;
    attr = new UIStringAttributes {
      Font = new UILabel ().Font
    };
  }
  public override SizeF GetSizeForItem (UICollectionView collectionView, UICollectionViewLayout layout, NSIndexPath indexPath)
  {
    string text = items [indexPath.Row];
    return new NSString (text).GetSizeUsingAttributes (attr);
  }
}

This code results in a Collection View where each cell fits the text it contains:

self sizing cells

Creating cells that are self-sized is much easier in iOS 8. Simply set the EstimatedItemSize on the UICollectionViewFlowLayout and implement SizeThatFits or use AutoLayout in the cell class.

For example, to self-size the cells in the example above, set EstimatedItemSize as shown below:

flowLayout = new UICollectionViewFlowLayout (){
  EstimatedItemSize = new SizeF (44, 144)
};

Then, simply adding the following implementation of SizeThatFits in the cell class produces the same result, without the need for the UICollectionViewDelegateFlowLayout implementation:

public override SizeF SizeThatFits (SizeF size)
{
  label.Frame = new RectangleF (new PointF (0, 0), label.AttributedText.Size);
  return label.AttributedText.Size;
}

Adjusting Layout Attributes in Cells

iOS 8 also makes it easier to manipulate the layout attributes returned from within the cell class without resorting to a UICollectionViewDelegateFlowLayout. Just override PreferredLayoutAttributesFittingAttributes in the cell class.

The following code changes the font of every other label and adjusts the layout for each cell appropriately:

public override UICollectionViewLayoutAttributes PreferredLayoutAttributesFittingAttributes (UICollectionViewLayoutAttributes layoutAttributes)
{
  var newLayoutAttributes = (UICollectionViewLayoutAttributes)layoutAttributes.Copy ();
  if (layoutAttributes.IndexPath.Row % 2 == 0) {
    //
    label.TextColor = UIColor.Red;
    ContentView.BackgroundColor = UIColor.LightGray;
    var attr = new NSAttributedString (Text, UIFont.SystemFontOfSize (28.0f));
    label.Font = UIFont.SystemFontOfSize (28.0f);
    //
    newLayoutAttributes.Frame = new RectangleF (new PointF (0, 0), attr.Size);
    label.Frame = new RectangleF (new PointF (0, 0), attr.Size);
  } else {
    //
    newLayoutAttributes.Frame = new RectangleF (new PointF (0, 0), label.AttributedText.Size);
    label.Frame = new RectangleF (new PointF (0, 0), label.AttributedText.Size);
  }
  return newLayoutAttributes;
}

This allows fine-grained control at the cell level, as shown below:

layout attributes

As you can see, iOS 8 adds flexibility to Collection Views, allowing granular control of cells directly from the cell class and making it easier to control cell layout and sizing when needed.

The code from this post is available here.

Discuss this blog post in the Xamarin Forums

July 15, 2014 4:21 GMT

Mobile .NET Meetups and Xamarin 3 Celebrations in July

We’ve had some amazing Xamarin 3 celebrations over the last few months, but we aren’t done just yet. This month, Mobile .NET developer groups around the world are joining in to celebrate the latest Xamarin release with pizza, cake, and in-depth sessions on all of the new features in Xamarin 3. We have also launched a brand new Twitter account, @XamarinEvents, which will regularly tweet about upcoming Xamarin and community events.

Xamarin Cake

Here are some upcoming Xamarin developer group meetups:

Nashville Xamarin User Group us

  • Nashville, TN: Tuesday, July 15th 6:30PM

  • Xamarin.Forms Demo & Lab

Austin Mobile .NET Developers Group us

  • Austin, TX: Wednesday, July 16th 6:30PM
  • Cross Platform Development with Portable Class Libraries

Portland Area .NET Users Group in

  • Portland, OR: Thursday, July 17th 6:00PM
  • Creating UIs for Cross-Platform Apps with Xamarin, with Xamarin’s James Montemagno

Los Angeles Mobile .NET Developers Group in

  • Los Angeles, CA: Monday, July 21st 7:00PM
  • Xamarin Basics

Israel .NET Developer Group il

  • Tel Aviv, Israel: Tuesday, July 22nd 5:30PM
  • Building Cross Platform Apps with Xamarin

Minnesota Enterprise Mobile in

  • Wayzata, MN: Tuesday, July 22nd 5:30PM
  • Building iOS User Interfaces with Xamarin

Northwest Valley .NET User Group in

  • Glendale, AZ: Wednesday, July 23rd 6:00PM
  • Building iOS, Android, and Windows Apps in C# with Xamarin, with Xamarin’s James Montemagno

Boston Mobile C# Developers Group us

  • Cambridge, MA: Thursday, July 24th 6:00PM
  • Introduction to Xamarin.Forms, with Xamarin’s Pierce Boggan

Arizona – Xamarin us

  • Scottsdale, AZ: Thursday, July 24th 6:00PM
  • Xamarin 3! iOS and Android Development in C# with Xamarin

Chicago .NET Mobile Developers us

  • Chicago, IL: Thursday, July 31st 5:45PM

  • Introduction to the MVVMCross Cross Platform Framework

Xamarin events are always happening around the world, so if you don’t see your city listed above, be sure to also check out the Xamarin Events forum where new meetups are being added all the time. Additionally, don’t forget to follow our brand new @XamarinEvents Twitter account to make sure you never miss an upcoming Xamarin event.

Don’t see a developer group in your area and want to get one started? We’re here to help! We have a tips and tricks guide on starting a developer group, our introduction to Xamarin slide deck, and of course our community sponsorship program to get you on your way. We also want to hear from you, so please feel free to send us an email or tweet @XamarinHQ so we can help spread the word and continue to grow the Xamarin community.

July 14, 2014 4:10 GMT

Core Motion in iOS 8 and Xamarin

Core Motion is having an update with the introduction of iOS 8 and we get several new classes to play with.

CMPedometer

The first of these being CMPedometer, this looks to take the place of CMStepCounter which came about with iOS 7. What do we get over and above the old step counter? Here is the new data broken down:

  • Number of steps
  • Distance travelled
  • Speed (Based on calculating from distance over time)
  • Floors ascended (Requires information about the building to be available)
  • Floors descended (Requires information about the building to be available)

The implementation of this is really simple and looks a little like this:


public override async void ViewDidLoad ()
{
   base.ViewDidLoad ();

   this.pedometer = new CMPedometer ();
   this.pedometer.StartPedometerUpdates (new NSDate (), this.UpdatePedometerData);

   var data  = await this.pedometer.QueryPedometerDataAsync (DateTime.SpecifyKind (DateTime.Now.AddHours(-24), DateTimeKind.Utc), DateTime.Now);
   this.UpdatePedometerData(data, null);
}

private void UpdatePedometerData(CMPedometerData data, NSError error)
{
   if (error == null) {
      this.InvokeOnMainThread (() => {
         this.StepsLabel.Text = string.Format ("You have taken {0:0.00} steps", data.NumberOfSteps);
         this.DistanceLabel.Text = string.Format ("You have travelled {0:0.00} meters", data.Distance.DoubleValue);
         
         var endTime = DateTime.SpecifyKind(data.EndDate, DateTimeKind.Utc);
         var startTime = DateTime.SpecifyKind(data.StartDate , DateTimeKind.Utc);
         var time = endTime.Subtract(startTime);
         var speed = data.Distance.DoubleValue / time.TotalSeconds;
         this.SpeedLabel.Text = string.Format ("Your speed was {0:0.00} meters a second", speed);
         
         this.FloorsAscendedLabel.Text = string.Format("You have ascended {0} floors", data.FloorsAscended);
         this.FloorsDescendedLabel.Text = string.Format("You have descended {0} floors", data.FloorsDescended);
      });
   }
}

CMAltimeter

The second class brand new to iOS 8 is CMAltimeter which seems to point to the new hardware to be made available with the next iteration of the iPhone / iPad. The main function here is to get the relative altitude of the device but this is currently not supported on any available hardware.

Here is a look at the implementation though as it stands:


public override void ViewDidLoad ()
{
   base.ViewDidLoad ();
   if (CMAltimeter.IsRelativeAltitudeAvailable) {
      this.altimeter = new CMAltimeter ();
      this.altimeter.StartRelativeAltitudeUpdates (NSOperationQueue.MainQueue, this.UpdateAltitudeData);
   } else {
      this.AltitudeLabel.Text = "Your device does not have required hardware for altitude..";
   }
}

private void UpdateAltitudeData(CMAltitudeData data, NSError error)
{
   this.InvokeOnMainThread (() => {
      this.AltitudeLabel.Text = string.Format ("Your relative altitude is {0}", data.RelativeAltitude);
   });
}

I think just based on these 2 new classes we can tell the context is going to be huge moving forward, whether you think it is an invasion of privacy or an innovation that your mobile device knows how many flights of stair you have claimed that day is a question that only you can answer. All i can say is that as app developers we have lots of options moving forward.

Get the source over at GitHub.


July 11, 2014 7:45 GMT

Exploring HealthKit With Xamarin: Provisioning and Permissions Illustrated Walkthrough

One of the more interesting frameworks in iOS 8 is Health Kit, system-wide persistent storage for health-related information. I’m just beginning to explore the namespace myself, but thought I’d walk through the steps you need to manipulate Health Kit with Xamarin.

Because health-related information is so sensitive, developing for Health Kit requires:

  1. The app be developed using an “Explicit App ID” with Health Kit Services explicitly enabled (see below);
  2. The Entitlements.plist must have a com.apple.developer.healthkit key set to true; and
  3. At initial runtime, the user must grant access via a detailed permissions dialog

Additionally, it’s worth emphasizing the importance of checking error codes in Health Kit API function calls. If a user does not grant permission or if for any other reason the app makes a call to a non-permitted API, this does not raise an exception. Rather, a null or otherwise empty result will be returned and typically an out NSError or closure-parameter will be set.

Provisioning and Permissions

Xamarin has a great article on device provisioning, but just to hit the highlights for Health Kit:

You need to set an “Explicit App ID” and explicitly enable “Health Kit” as an app service. Here, I’m created an ID for an app whose ID is “{PREFIX}.com.xamarin.HKWork”:

Screen-Shot-2014-07-11-at-7.49.46-AM

Screen Shot 2014-07-11 at 7.51.14 AM

After you do that, you’ll have to create a new provisioning profile for this App ID:

Screen Shot 2014-07-11 at 7.59.17 AM

Once you’ve awaited the generation of the profile, download it and double-click to install it on your development system:

Screen Shot 2014-07-11 at 8.05.17 AM

Now, in your Xamarin Studio project, open your Info.plist and set the Bundle Identifier to your explicit App ID (without the team prefix):

Screen Shot 2014-07-11 at 8.56.35 AM

And set your project’s Bundle Signing options so that you are using your new provisioning profile:

Screen Shot 2014-07-11 at 8.14.07 AM

(Now that I’ve written that, I suspect that you can probably leave it as “Automatic”, since the App ID is explicitly the same as that in the custom provisioning profile: that’s how the two are matched by the system. But still, I’m going to leave the step just to be clear what’s happening. And I don’t think there’s any harm in setting the provisioning profile explicitly.)

You’ve taken care of Info.plist, so now open Entitlements.plist. (Some project templates don’t automatically generate an Entitlements.plist file. If your project doesn’t have one, use File/New File…/iOS and choose Entitlements.plist.) Click on “Source” and add a new key com.apple.developer.HealthKit of type Boolean with a value of Yes (== true):

Screen Shot 2014-07-11 at 9.14.53 AM

Write code to request permission from the app user

To use Health Kit, the user must grant your app access. This involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);

var hks = new HKHealthStore ();
hks.RequestAuthorizationToShare (new NSSet (new [] { tempQuantityType }), new NSSet (), (success, error) => {
	Console.WriteLine ("Authorized:" + success);
	if (error != null) {
		Console.WriteLine ("Authorization error: " + error);
	}
});

Here, we are requesting authorization to share body temperature data (i.e., “share data generated by my app with the HealthStore database”). When this app is run, the user will be presented with the Health Kit permissions dialog, which will give the user fine-grained control over the requested types of data you’ll share. In this case, for instance, the dialog inside the Health app looks like this:

IMG_1314

Write a brilliant app

I have no insight into how to do that.

… that has some health-related information

Oh good, I can help with that.

Creating and storing data in the shared HealthKit store involves these API calls:

var temperatureKey = HKQuantityTypeIdentifierKey.BodyTemperature;
var tempQuantityType = HKObjectType.GetQuantityType (temperatureKey);
var myCurrentTemp = HKQuantity.FromQuantity (HKUnit.DegreeFahrenheit, 98.6);
var meta = NSDictionary.FromObjectAndKey (new NSNumber (4), HKMetadataKey.BodyTemperatureSensorLocation);
var tempSample = HKQuantitySample.FromType (tempQuantityType, myCurrentTemp, new NSDate (), new NSDate (), meta);

hks.SaveObject(tempSample, (success, error) => {
	Console.WriteLine("Write succeeded: " + success);
	if(error != null)
	{
		Console.WriteLine(error);
	}
});

I trust it’s obvious that the types of data you attempt to store must match those you’ve requested permission from the end-user and that your error-handling should be considerably more sophisticated (since it’s incredibly possible that app users are going to be very cautious about allowing access to their medical data, even if it’s clearly central to the app’s value).

The resulting shared data (assuming that permissions are granted) looks like this in the Health app:

image1

Notice that although I created the data using Fahrenheit, in this case it’s being displayed as Celsius (which I imagine is the opposite of the likely use-case!). Units of measure and conversions are built in to Health Kit, which I’ll cover in a later post. For now, though: Happy Healthing!

July 11, 2014 6:04 GMT

My Xamarin Studio F# Wishlist

I am writing a large iOS and OS X app in F# and am totally digging the honeymoon phase. Not only is F# a crazy powerful language, but it has a great interactive code executer built right into the IDE. In all, it’s a wonderful development experience.

(If you haven’t seen it, check out my hastily recorded Interactive F# Development in Xamarin Studio video.)

While F# in Xamarin Studio is great, it does lack a few features I miss from the C# experience. These include:

Sorted Intellisense. If you didn’t know, you can hold the Shift key while upping and downing through the Intellisense to switch to an inheritance sorted list of members. This is not only useful, but critical to exploring new objects and APIs. It also lets you filter out all the junk that comes with base classes (I’m looking at you NSObject). I miss this feature so, so much (imagine creepy Anakin Skywalker saying that).

Expand Selection using the AST. Another important but often missed feature of Xamarin Studio’s editor is the ability to expand your selection based on the language’s syntax tree. If you have the text “fo|o + bar”, then expand the selection, you get “[foo] + bar”. Expand again, and you get “[foo + bar]”. This is an amazing keyboard shortcut that services quick identifier selection, expression selection, method selection, and more.

Rename Refactoring. You know, you don’t think of it much, but when someone takes away your rename refactoring, you all of a sudden are back in the 1990’s coding in Turbo Pascal with your crappy IBM PS/2 debating whether code clarity is worth the trouble…

Thanks to Don Syme for setting me straight: Xamarin Studio supports Rename and it works great (even across projects). I’m going to meditate a bit on how it’s possible to be completely blind to a feature.

Search for Definition. MonoDevelop used to have a great tool for jumping to any definition in your code. Just hit Cmd + . and you get a great search window. Xamarin Studio screwed this up a bit by putting the window in your peripheral vision and limiting the results to just a few items with not enough info to distinguish them. But I digress. Even in its not-very-useful state, I still wish I could search for and jump to definitions in F# code more easily.

NUnit IDE Integration. Xamarin Studio has shortcut “test bubbles” in C# code when using NUnit. These bubbles are right in the editor with the code so it makes running and debugging tests a two click task. While F# of course supports NUnit testing, the editor doesn’t care. Too bad.

And then the crashing. Hey, it sucks to be on the frontier, software sometimes breaks and needs time to be refined. I just wish I could go more than 5 minutes without Intellisense crashing or more than 15 minutes without Xamarin Studio crashing. Coding F# with functioning Intellisense would be so groovy…

What’s the good news? The Xamarin Studio F# integration is open source! That means I should “put up or shut up”. I have a small amount of experience writing XS addins and a small amount of experience coding F# - I figure this qualifies me to at least send a pull request. Wish me luck!

July 11, 2014 3:00 GMT

Xamarin on Film: @dotnetConf & FlashCast

Earlier this year, Xamarin invaded Channel 9′s Visual Studio Toolbox and Dev Radio shows. Response to all 6 shows has been amazing, with over 325,000 views so far! Now, we’re back again with even more great videos for your weekend enjoyment.

dotnetconflogo

Microsoft hosted their second dotnetConf, a free online conference, in June, and Xamarin was there in full force. I’ve included my talk Developing Native iOS, Android, and Windows Apps with Xamarin below, which you can find, with all of the great .NET related videos from this year’s conference, on Channel 9.

FlashCast is a brand new web series offering unique, 15-minute webinars on awesome topics. Evangelist Mike Bluestein kicked off the very first FlashCast with Build your first iOS App with Visual Studio and Xamarin, included below:

Our next entry in the FlashCast series was on how to Build your first Android app with Visual Studio and Xamarin:

Stay tuned over the next few weeks for even more new FlashCast episodes featuring Xamarin!

July 11, 2014 4:25 GMT

Adding Touch ID Authentication in iOS 8

It has now become very easy to ensure the person using your app is the owner of the iOS device it is running on. To add this takes only a few lines of code.

TouchId

partial void LoginPressed (UIButton sender)
{
   var context = new LAContext ();

   var error = new NSError ();
   if (context.CanEvaluatePolicy (LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error)) {
      var replyHandler = new LAContextReplyHandler((success, err) => {
         this.InvokeOnMainThread(() => {
            if(success){
               Console.WriteLine("You Logged in");
            } else {
               var errorAlertView = new UIAlertView("Login Error", err.LocalizedDescription, null, "Close");
               errorAlertView.Show();
            }
         });
      });
      context.EvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, "You need to login", replyHandler);
   }
}

That’s all there is to it! The power and security of fingerprint authentication all wrapped up in a simple API.

you can grab the same project here


July 11, 2014 3:11 GMT

What's new in ReactiveUI 6: ReactiveCommand<T>

One of the largest breaking changes in ReactiveUI 6.0 is the new ReactiveCommand. Since this change is the most likely one to mess with your existing code, I wanted to make sure to get the blog post about it as soon as possible.

What was wrong with the old ReactiveCommand?

There are a few parts of the existing ReactiveCommand design that made certain scenarios particularly difficult to deal with. The original scenario that motivated this rewrite was the following (simplified for effect):

"In GitHub for Windows, the Sync Command is an invocation of the Pull Command followed by the Push Command - how can I create a Command whose CanExecute turns off until the Pull then the Push completes?"

The only one who received the completion that the background method for Pull and Push completed was the person who set it up (i.e. the one who called RegisterAsyncXYZ). Other callers had to do something really hacky:

someCommand.IsExecuting.Where(x => x == false).Skip(1).Take(1);  

The even more common scenario was, "Write a test that invokes a Command with a background method, then wait for the result".

With the new ReactiveCommand and the ExecuteAsync method, the GitHub for Windows scenario becomes very easy:

var canSync = Observable.CombineLatest(  
    Push.CanExecuteObservable, Pull.CanExecuteObservable,
    (pl,pu) => pl && pu);

Sync = ReactiveCommand.CreateAsyncTask(canSync, async _ => {  
    await Pull.ExecuteAsync();
    await Push.ExecuteAsync();
});

The test scenario similarly becomes much more straightforward:

var fixture = new CoolViewModel();  
var result = await fixture.ExecuteAsync();  
Assert.NotNull(result);  

Creating ReactiveCommands

ReactiveCommand is now a Generic class - before, Subscribing to ReactiveCommand would give you the (relatively useless, Worst Practice) CommandParameter. Now, Subscribing to ReactiveCommand gives you the result of your background method after it finishes.

To facilitate this, the correct way to create ReactiveCommands is now via a static ReactiveCommand.CreateXYZ family of methods. Create lets you provide both the canExecute as well as providing the method you used to provide to RegisterAsync.

Dual-Mode Zen Nature: ExecuteAsync vs. Subscribe

ReactiveCommand now has two complimentary ways to get the result of your background method:

  • Subscribing to the Command itself gives you a stream of all results - this is very convenient to connect to a property on the ViewModel via ToProperty

  • ExecuteAsync returns a single invocation of the background method. This is useful for invoking a Command as part of a larger workflow, or for testing the background method of a Command. Both the awaiter and any Subscribers to the Command will receive the results.

Some Before => Afters

Before:

// Create a simple command
var someCmd = new ReactiveCommand();  
someCmd.Subscribe(_ => Console.WriteLine("Cool it was invoked!"));

// Create an async command
var asyncCmd = new ReactiveCommand(myCanExecute);

asyncCmd.RegisterAsyncTask(x => doAThingAsync())  
    .ToProperty(this, x => x.OutputText, out outputText);

After:

// Create a simple command
var someCmd = ReactiveCommand.Create();  
someCmd.Subscribe(_ => Console.WriteLine("Cool it was invoked!"));

// Create an async command
var asyncCmd = ReactiveCommand.CreateAsyncTask(myCanExecute, x => doAThingAsync());

asyncCmd.ToProperty(this, x => x.OutputText, out outputText);  
July 10, 2014 10:59 GMT

Welcome to ReactiveUI 6.0

After 8 months of work, 878 commits, and 1032 files changed, ReactiveUI 6.0 is finally released, the biggest RxUI release ever! A huge thanks to our contributers for this release:

  • Johan Laanstra
  • Oren Novotny
  • Todd Berman
  • Michael Teper
  • Felipe Lessa
  • Amy Palamountain
  • Dennis Daume
  • Rik Bosch
  • James Nugent
  • Phil Haack
  • Maratoss
  • David Lechner
  • Justin Manus
  • Keith Dahlby
  • Markus Olsson

In particular, a huge thanks goes to Johan, who has done an enormous amount of great work on this release. Thank you so much!

Migrating from existing code

We've written a migration guide to help existing application authors migrate their 5.x applications to ReactiveUI 6.0. Check out this document before updating your dependencies to get a heads-up as to what you're in for.

What's New in ReactiveUI 6.0

Over 120 new features were merged into ReactiveUI 6.0, trying to sum them all up is a huge undertaking! Here are some of the highlights:

Universal Windows Phone app and Xamarin Forms Support

ReactiveUI 6.0 has great support for all of the latest developer platforms, including WinRT Universal Apps as well as support for the new Xamarin Forms UI toolkit via the new ReactiveUI-XamForms NuGet package. Use either the updated Portable Library support, or use the new Shared Projects tooling in Visual Studio.

Existing support for Android and iOS has also been greatly improved, including support for unit test runners on those platforms, as well as creating Observable abstractions for all events via the ReactiveUI-Events package. Helpers for the Android Support Library are now also provided, via the ReactiveUI-AndroidSupport package.

ReactiveUI 6.0 supports the following platforms (In order of personal developer joy):

  • Xamarin.Android
  • Xamarin.iOS
  • Xamarin.Mac
  • Xamarin Forms (iOS + Android + WP8)
  • .NET 4.5 (WPF and Windows Forms, via ReactiveUI-WinForms)
  • Universal Windows Apps (WPA81)
  • Windows Phone 8.0 Apps (Silverlight-based)
  • Windows Store Apps (WinRT)

ReactiveUI makes creating list-based views a snap

We've added great support for recycling list-based views on iOS and Android (UICollectionView and UITableView on iOS, ListAdapter on Android). These new adapter classes allow you to map a ReactiveList of ViewModel objects and automatically create and recycle the associated views, for high-performance lists without writing a ton of boilerplate code.

On iOS, added and removed items will even be automatically animated in and out. On Android, we help you easily implement the ViewHolder pattern to limit the amount of work done while scrolling.

Large Application Performance

One of the focuses of this release has been performance and memory usage in large applications. ReactiveUI 6.0 is much less prone to creating memory leaks in application code via WeakEventManager, as well as more performant by eliminating scheduling latency as much as possible. Other features, such as View and ViewModel Activation, allow you to create and clean-up objects only when the View is actually visible on-screen, saving a lot of unnecessary work.

While some of these changes will require you to update your application and unit tests, the end result is an application that uses less memory and feels more responsive.

The same Rx, Everywhere

ReactiveUI 5.x used a separate installation of the Reactive Extensions for .NET for Xamarin projects, which made creating proper Portable Libraries more difficult. RxUI 6.0 now resolves this completely, and you can now build ViewModels that work on every supported platform.

Questions, Comments, Concerns?

There are three great venues for problems / questions related to this release:

July 10, 2014 4:32 GMT

The Protocol Pattern

In C# (and F#), one can define extension methods on interfaces. These extension methods can have implementations, which can be used as default implementations for implementors of the extension. I haven’t heard a name for this technique.

Example:

interface IFoo
{

}

static class IFoo_Extensions 
{
	public static void Foo(this IFoo self) { Console.WriteLine("Foo"); }
}

class ImplementingClass : IFoo
{

}


class MainClass
{
	public static void Main (string[] args)
	{
		var aFoo = new ImplementingClass ();
		aFoo.Foo (); //Prints "Foo" from extension default implementation

	}
}

Xamarin uses this pattern extensively when binding Objective-C Protocols, which are essentially interfaces with optional methods. For instance, if you have an interface where some methods must be implemented by the library user but some aren’t, you can do this:

interface IFoo
{
	//Methods defined here, as always, must be implemented
	void Necessary ();
}

static class IFoo_Extensions
{
	//"Optional" methods defined here with default implementations
	public static void Optional (this IFoo self)
	{
	}
}

class ImplementingClass : IFoo
{
	public void Necessary ()
	{
		Console.WriteLine ("Necessary");
	}

//    public void Optional()
//    {
//        Console.WriteLine("Overridden");
//    }

}

Obviously, it’s not exactly the same to have a default implementation defined in an extension method as it is to have an optional method that simply does not exist. But conceptually it’s close enough that I’ve started referring to this technique as the “Protocol Pattern.”

Thoughts?

July 09, 2014 7:23 GMT

Adding View Effects in iOS 8

In iOS 8, Apple has added UIKit level support for effects such as blur and vibrancy. These effects are seen in system-level UIs such as the blur effect shown when opening a folder or swiping to the lock screen, and can now be added to your own applications with just a few lines of code.

view effects

Blur Effect

The first effect you can use is the blur effect, represented by the UIBlurEffect class. Adding a blur effect is easy. Create a UIBlurEffect and a UIVisualEffectView from the effect. Then just add the effect view to the view hierarchy.

For example, the following code adds a blur effect:

var blur = UIBlurEffect.FromStyle (UIBlurEffectStyle.Light);
var blurView = new UIVisualEffectView (blur) {
  Frame = new RectangleF (0, 0, imageView.Frame.Width, 400)
};
View.Add (blurView);

This code dynamically blurs the content beneath it. For instance, when added to a view hierarchy containing a scrollable image, the effect of the blur changes at runtime as the image is moved:

blur

The blur effect comes in three styles:

  • UIBlurEffectStyle.Light
  • UIBlurEffectStyle.ExtraLight
  • UIBlurEffectStyle.Dark

These change the appearance of the blur as shown below:

blur style

Vibrancy Effect

In addition to blur, iOS includes a vibrancy effect (UIVibrancyEffect), which allows content displayed over a blur to remain legible. Vibrancy effects are created from blur effects, and are also displayed using a UIVisualEffectView. Any view the effect should be applied to is added as a subview of the UIVisualEffectView‘s ContentView.

For example, the following code adds a label to be displayed over the blurred view created above:

// vibrancy view
var frame = new Rectangle (10, 10, 100, 50);
var vibrancy = UIVibrancyEffect.FromBlurEffect (blur);
var vibrancyView = new UIVisualEffectView (vibrancy) {
  Frame = frame
};
label = new UILabel {
  Text = "Hello iOS 8!",
  Frame = vibrancyView.Bounds
};
vibrancyView.ContentView.Add (label);
blurView.ContentView.Add (vibrancyView);

When the user scrolls the image, the blur changes and the label’s text is modified dynamically such that it remains readable:

vibrancy

These effects are useful when you want them applied dynamically. Of course, rendering them has some cost, so if you can get the results you are looking for with a static effect, that should be used. However, for creating a level of polish, with a sense of depth on par with iOS itself, it’s nice to now have these features available.

The code from this post is available here.

Discuss this blog post in the Xamarin Forums

 

July 07, 2014 3:59 GMT

Build Great Photo Experiences in iOS 8 with PhotoKit

PhotoKit is a new framework in iOS 8 that allows you to query the system image library and create custom user interfaces to view and modify its contents. To use PhotoKit from Xamarin.iOS, you can download the preview release in our alpha channel.

PhotoKit1

PhotoKit includes a number of classes that represent image and video assets, as well as collections of assists such as albums and folders. Collectively, PhotoKit represents these in what it calls model objects.

The model objects that represents the photos and videos themselves are of type PHAsset. A PHAsset contains metadata such as the asset’s media type and its creation date.

Similarly, the PHAssetCollection and PHCollectionList classes contain metadata about asset collections and collection lists respectively. Asset collections are groups of assets, such as all the photos and videos for a given year. Likewise, collection lists are groups of asset collections, such as photos and videos grouped by year.

PhotoKit makes it easy to query model data through a variety of fetch methods. For example, to retrieve all images, you would call PFAsset.Fetch, passing the PHAssetMediaType.Image media type.

PHFetchResult fetchResults = PHAsset.FetchAssets (PHAssetMediaType.Image, null);

The PHFetchResult instance would then contain all the PFAsset instances representing images. To get the images themselves, you use the PHImageManager (or the caching version, PHCachingImageManager) to make a request for the image by calling RequestImageForAsset. For example, the following code retrieves an image for each asset in a PHFetchResult to display in a collection view cell:

public override UICollectionViewCell GetCell (UICollectionView collectionView, NSIndexPath indexPath)
{
  var imageCell = (ImageCell)collectionView.DequeueReusableCell (cellId, indexPath);
  imageMgr.RequestImageForAsset ((PHAsset)fetchResults [(uint)indexPath.Item], thumbnailSize,
    PHImageContentMode.AspectFill, new PHImageRequestOptions (), (img, info) => {
      imageCell.ImageView.Image = img;
    });
    return imageCell;
}

This results in a grid of images as shown below:

PhotoKit1

That’s how to handle querying and reading data. You can also write changes back to the library. Since multiple interested applications are able to interact with the system photo library, you can register an observer to be notified of changes using a PhotoLibraryObserver. Then, when changes come in, your application can update accordingly. For example, here’s a simple implementation to reload the collection view above:

class PhotoLibraryObserver : PHPhotoLibraryChangeObserver
{
  readonly PhotosViewController controller;
  public PhotoLibraryObserver (PhotosViewController controller)
  {
    this.controller = controller;
  }
  public override void PhotoLibraryDidChange (PHChange changeInstance)
  {
    DispatchQueue.MainQueue.DispatchAsync (() => {
      var changes = changeInstance.GetFetchResultChangeDetails (controller.fetchResults);
      controller.fetchResults = changes.FetchResultAfterChanges;
      controller.CollectionView.ReloadData ();
    });
  }
}

To actually write changes back from your application, you create a change request. Each of the model classes has an associated change request class. For example, to change a PHAsset, you create a PHAssetChangeRequest. The steps to perform changes that are written back to the photo library and sent to observers like the one above are:

  1. Perform the editing operation.
  2. Save the filtered image data to a PHContentEditingOutput instance.
  3. Make a change request to publish the changes form the editing output.

Here’s an example that writes back a change to an image that applies a core image noir filter:

void ApplyNoirFilter (object sender, EventArgs e)
{
  Asset.RequestContentEditingInput (new PHContentEditingInputRequestOptions (), (input, options) => {
    //
    // perform the editing operation, which applies a noir filter in this case
    var image = CIImage.FromUrl (input.FullSizeImageUrl);
    image = image.CreateWithOrientation ((CIImageOrientation)input.FullSizeImageOrientation);
    var noir = new CIPhotoEffectNoir {
      Image = image
    };
    var ciContext = CIContext.FromOptions (null);
    var output = noir.OutputImage;
    var uiImage = UIImage.FromImage (ciContext.CreateCGImage (output, output.Extent));
    imageView.Image = uiImage;
    //
    // save the filtered image data to a PHContentEditingOutput instance
    var editingOutput = new PHContentEditingOutput(input);
    var adjustmentData = new PHAdjustmentData();
    var data = uiImage.AsJPEG();
    NSError error;
    data.Save(editingOutput.RenderedContentUrl, false, out error);
    editingOutput.AdjustmentData = adjustmentData;
    //
    // make a change request to publish the changes form the editing output
    PHPhotoLibrary.GetSharedPhotoLibrary.PerformChanges (
      () => {
        PHAssetChangeRequest request = PHAssetChangeRequest.ChangeRequest(Asset);
        request.ContentEditingOutput = editingOutput;
      },
      (ok, err) => Console.WriteLine ("photo updated successfully: {0}", ok));
  });
}

When the users selects the button, the filter is applied:

PhotoKit2

And thanks to the PHPhotoLibraryChangeObserver, the change is reflected in the collection view when the user navigates back:

PhotoKit3

PhotoKit is a welcome addition to iOS that allows greater flexibility for incorporating photo library data into applications. It opens the doors for third party developers to build more integrated photo and video experiences than ever before.

The code from this post is available in my GitHub repo.

Discuss this blog post in the Xamarin Forums

July 05, 2014 11:13 GMT

Port of Floating Action Button

Android L has introduced something called a Floating Action Button (FAB), which is basically a circle overlayed on top your application. This FAB can be clicked to do an action. In the Google+ application this is used to persistently allow the user to create a new post.


It basically looks like in the screenshot above, where you can see a circle with a play icon at the bottom of the screen. Faiz Malkani backported this from Android L to work on JellyBean and KitKat, and I took the liberty to port it to Xamarin.Android.

You can find the repository on GitHub along with a sample application, which the screenshot above is from.
July 03, 2014 8:28 GMT

Contest: Build Your First F# Mobile App

Experience the power of building native mobile apps in F# with Xamarin.

What’s better than F# week? F# weekend! We’re announcing another contest to commemorate this programming language in a new contest. Earlier this week, we started F# week off by announcing our “Run an F# app, get an F# shirt” campaign. Tuesday and Wednesday, Microsoft F# MVP Rachel Reese taught us the basics of F#, and even built a simple task-management app.

Today, we are inviting you to dive into building native mobile apps in F# with our newest contest. Creating a mobile app with F# is as easy as File -> New -> F# -> iOS or Android within Xamarin Studio.

How to Enter

  1. Install Xamarin 3
  2. File -> New -> F# -> iOS or Android in Xamarin Studio
  3. Build an succinct, expressive native mobile app using F#
  4. Tweet your entry with a picture of your F# app running and this text:
    I just built my first F# mobile app using @XamarinHQ:  http://xamar.in/r/fsharp

2014-07-01_1728

How to Win

Want to stack the cards in your favor? Do any or all of the following to increase your odds of winning:

  • Build something cool
  • Utilize F# language features
  • Blog about your experience
  • Open-source your app

Prizes

Not sure where to begin? Xamarin evangelist James Montemagno has put together a list of some guides, samples, and apps to help get you started. If you are new to mobile development or Xamarin and want to get started today, visit xamarin.com/download.

All submissions must be made by Monday, July 21st at 8AM EDT. We will evaluate each app and choose a winner. A valid entry consists of a tweet with screenshot(s) of your F# app running. Other factors considered will include novelty, code quality, and reliability. Winners will be announced on Twitter. Contestants should follow @xamarinhq to enable us to DM you for private follow-up. There is no purchase necessary to enter the Build Your First F# Mobile App contest.

July 03, 2014 6:19 GMT

Local Notifications in iOS 8 With Xamarin

As of iOS 8, the user has to provide explicit permission for apps to respond to local notifications. This means that now, the first time the program is run, you need to run code such as:

//F#
UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert 
    ||| UIUserNotificationType.Badge 
    ||| UIUserNotificationType.Sound, 
    new NSSet())
|> UIApplication.SharedApplication.RegisterUserNotificationSettings

or

//C#
var settings = UIUserNotificationSettings.GetSettingsForTypes(
    UIUserNotificationType.Alert 
    || UIUserNotificationType.Badge 
    || UIUserNotificationType.Sound, 
    new NSSet());
UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);

Which will present a user dialog. When they complete that dialog, the system will call the UIAppDelegate.DidRegisterUserNotificationSettings method. You can check the status using UIApplication.CurrentUserNotificationSettings.

If you try to send a notification without these settings being allowed, you will get a runtime error of the form:

Attempting to schedule a local notification {...} with an alert but haven't received permission from the user to display alerts
Attempting to schedule a local notification {...} with a sound but haven't received permission from the user to play sounds
Attempting to schedule a local notification {...} with a badge number but haven't received permission from the user to badge the application
July 03, 2014 2:40 GMT

Awesome Samples to Jumpstart F# Mobile Development

Throughout the week we have seen a wide assortment of F# samples and applications that you can use to jump start your F# mobile development. Here are a few new resources available to developers, including full sample applications comprised of beautiful F# source code.

F# Tutorial

Starter Guides

With the release of Xamarin 3, we brought first class F# support to developers inside of Xamarin Studio. To go along with that, we also have great getting started documentation, along with a few other fantastic resources to get you going:

Mobile App Samples

F# Shallow App
In addition to documentation here are a few open source F# mobile apps that you can run right away.

Shallow

Based on popular dating apps, Shallow is a great example of using beautiful animations built into iOS, that you can take advantage of with a few lines of code in F#.

For a full break down of Shallow’s features and introduction to its F# goodness be sure to see the full blog post by Xamarin’s David Siegel, and its GitHub repo.

Tasky F#

Recently announced Xamarin Evolve speaker and F# enthusiast Rachel Reese wrote an amazing introduction to mobile development in F# post. Not only did she break down all of the benefits of F#, but also built out a full Task taking app, Tasky F#, that is completely open source on GitHub.

Xamarin Store

anuj f sharp shirtWhen we kicked off F# week, we released a brand new version of the Xamarin Store app for iOS and Android. This is where you can get your very own F# t-shirt shipped for FREE directly to your doorstep for trying Xamarin and running your first F# app. This is a beautiful application with elegant animations such as Ken Burn’s effects on images. Download the source code today and get your very own F# t-shirt.

Show us your F# Hacks!

These are a few great examples to help kick start your F# mobile development with Xamarin. We are sure might have your own F# tips and tricks to share with developers, so head over to our Community Forums and share your own F# hacks!

July 03, 2014 1:21 GMT

Screen Mirroring for iOS, Android, and Windows Phone

It is unfortunate that we don’t live in a world where we can use an iOS, Android, and Windows Phone emulators/simulators at the same time. Nested virtualization really messes things up and even if that worked the arm emulators for Android are a nightmare. Even on the PC side where I can use the wonderful x86 emulator (read my blog post on setup) for Android, you have to turn off hyper-v to get things to work, and of course there is no iOS simulator over there. So what is one to do? I have to use real devices and rely on screen mirroring to pull them simultaneous views of all of our devices for that WOW effect. Here are my recommended tools to get you going:

iOS Screen Mirroring


On the iOS side of things it is really simple as my hat goes off to AirSquirrels for their amazing app called Reflector. Using the power of AirPlay built into every iOS device you are easily able to stream your screen over WiFi to your PC or Mac. They didn’t stop there though as you can also do full screen recordings of your device and pick what device frame you want to use as well. The only downside is that you will need to fork over $13 for their software… twice if you want it on PC and Mac, but it is well worth it. The best part is nothing needs to be installed on your phone at all.

iOS Mirroring Alternatives
Reflector isn’t the only one out there as other have tapped into the AirPlay screen mirroring including AirServer and X-Mirage.

Warnings
Since all of these apps are based on AirPlay you will need to ensure the WiFi network allows AirPlay. This sometimes is an issue on public WiFi networks so I often have my own hotspot for this. Additionally, I have not gotten it to work inside of a PC VM on the mac, so I mirror directly to the Mac and that works great.

Android Screen Mirroring



I wrote about Android screen mirroring in the past and my opinion still hasn’t changed, as Mobizen is by far the best screen mirroring application out there. You install their app from Google Play and then install an app on your PC and you are good to go with screen mirroring over USB, which is great. They recently went through a big transition of introducing a horrible web version of the app, but have now merged them together.

Android Mirroring Alternatives
Mobizen offers a nice 1 to 1 mirroring, which is why I love it. However, it is only available on PC currently. So if you need to mirror on your Mac you will need a different option. Droid@Screen actually works pretty good. It is based on screen shots and usually runs at a low frame rate, but it gets the job done. In addition to that Google announced that you will be able to mirror your Android device to your Chromecast, but that does us little good if we want it on our Mac/PC.

Warnings
Mobizen requires about every permission under the sun so be aware of that. I haven’t had any real issues with that though as I run it on my developer devices. All apps are running things via ADB from my best knowledge so that might be a bit tricky and sometimes I reboot VS to get things going, but that isn’t too bad.

Windows Phone


With Windows Phone 8.1 it couldn’t be easier to screen mirror to your Windows PC as it is built right into the phone! All you need to do is install the “Project My Screen" app on your PC and you are good to go. As soon as you launch the app your Phone which is plugged in via USB will prompt you to mirror the screen.

There you have it screen mirroring for iOS, Android, and Windows Phone. Here is a demo:

July 02, 2014 10:59 GMT

F# For Scripting

It’s F# Week at Xamarin. Also, in the US, it’s only a 4-day work-week. F# saves 20% of your time. QED.

Anyway, I don’t have any actually interesting F# to share, but I recommend:

But what I thought I could quickly contribute is that:

  • F# is an awesome scripting language; and
  • Scripting may be the best way to learn F#

Scripting tasks often involve transforming a stream of text by repeatedly Filtering, Assigning, Reducing, Transforming, and Slicing it (“a sequence of FARTS“) and this is an area where the functional approach is pretty clearly easier to work with than the OOP approach of a network of cooperating objects.

And since scripting tasks are often private or semi-private low-complexity chores, they’re an excellent domain for regularly exercising your knowledge of a new language. It’s all well and good to carve out a couple weekends and work through a book but nothing beats regular exposure.

(While I’m on the subject, these are currently my favorite F# books. Initial exploration:

Deeper dives:

)

F# scripts are F# files with the .fsx extension. On OS X with mono, they can be run with fsharpi script.fsx or:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif
printfn "%A" fsi.CommandLineArgs

To add references, use #r:

#if run_with_bin_sh
  exec fsharpi --exec $0 $*
#endif

#r "System.Core.dll"
#r "System.Xml"

open System
open System.Xml.Linq
open System.IO

//...etc...

I’ve been using F# for scripting for more than a year now and I can honestly say that it’s displaced Ruby as my scripting language of choice.

Give it a shot!

July 02, 2014 6:36 GMT

Headed to the Capitol for Microsoft WPC 2014

Xamarin is headed to the capitol to meet with our rapidly growing network of partners, and to strike new relationships at Microsoft’s premier partner event this July.  We will be in Washington, D.C for Microsoft’s Worldwide Partner Conference at booth #828 to meet our community, learn about your apps, and connect with our partners.  

washington-dc

Join Xamarin for food and drinks during WPC week on Tuesday, July 15th from 7:30 pm to 10:30 pm. We’ll have a selection of delicious drinks and appetizers, and of course, plenty of mobile development talk. We look forward to seeing you there!

When: Tuesday, July 15th, 7:30pm – 10:30pm

Where: Redline Gastrolounge, 707 G Street Northwest, Washington, D.C. 20001

RSVP

Not at the Worldwide Partner Conference but in the DC area?  Stop by anyway! You and your friends are welcome. Make the most of your time at WPC and schedule dedicated time with the Xamarin partner team while you’re in town for the conference.

July 01, 2014 4:56 GMT

Xamarin Getting Started Sampler

There are many great resources for learning Xamarin, ranging from docs, samples and videos, to full-blown training via Xamarin University. If you’re just getting started, here are a list of resources to get you off to a good start. There are many other articles and samples as well in the Xamarin Developer Center, so it really depends upon your interests, but these are good fundamental topics in any case:

Xamarin.iOS:

Xamarin.Android:

Xamarin.Forms:

Also see:

And check out the recipes, samples and videos sections as well:


July 01, 2014 3:00 GMT

End to End Mvvm with Xamarin

As a Xamarin University instructor, I am occassionally asked how I would put together a typical MVVM based app while connecting to a remote service. This is not the only way to architect our apps, and may not be the best for your app. Your mileage may vary.

Our goal is to connect to a remote service api, download the data, convert into a model that we control, and bind it to our ui. We'll connect to a remote service to download technical conference information, and we'll utilize a handful of useful open source .net libraries to speed things along and make our code cleaner.

We'll be using Xamarin Studio 5 (although Visual Studio will work just fine), and we'll use Xamarin.Forms for our user interface. All of the code is available from my Github Repo

Create Solution

Start by creating a new solution. We'll be using the "Blank App (Xamarin.Forms Portable)" template under the "Mobile Apps" node. I prefer PCLs over Shared Projects, but that's just me. Shared Projects will work also. I'll name the solution "DtoToVm" This template will create a core Portable Class Library as well as an Android and an iOS project (and a Windows Phone app if you're using Visual Studio on Windows). We'll be putting almost all of our code in the shared PCL.

File -> New Solution -> Blank App (Xamarin.Forms Portable)

Remote Third Party API (JSON)

Let's take a look at the api that we'll be working with. For this example, I'll be using api.tekconf.com/v1/conferences an open source conference management system (written by me). When performing a GET request on the conferences uri, we're given a list of all of the active conferences in the system.

[
  {
    slug: "codestock-2014",
    name: "CodeStock 2014",
    start: "/Date(1405036800000)/",
    end: "/Date(1405123200000)/",
    callForSpeakersOpens: "/Date(1391619909000)/",
    callForSpeakersCloses: "/Date(1391619909000)/",
    registrationOpens: "/Date(1391619909000)/",
    registrationCloses: "/Date(1405036800000)/",
    description: "CodeStock is a two day event (July 11th & July 12th of 2014) for technology and information exchange. Created by the community, for the community – this is not an industry trade show pushing the latest in marketing as technology, but a gathering of working professionals sharing knowledge and experience. Join us at CodeStock 2014 and move into the future.",
    lastUpdated: "/Date(1392149694455)/",
    address: {
      streetNumber: 0,
      city: "Knoxville",
      state: "TN",
      postalArea: "US"
    },
    imageUrl: "http://tekconf.blob.core.windows.net/images/conferences/codestock-2014.png",
    imageUrlSquare: "http://tekconf.blob.core.windows.net/images/conferences/codestock-2014-square.jpg",
    isLive: true,
    homepageUrl: "http://www.codestock.org/",
    position: [
      -83.9207392,
      35.9606384
    ],
    defaultTalkLength: 60,
    rooms: [ ],
    sessionTypes: [ ],
    subjects: [ ],
    tags: [ ],
    sessions: [ ],
    numberOfSessions: 0,
    isAddedToSchedule: false,
    isOnline: false,
    dateRange: "July 11 - 12, 2014",
    formattedAddress: "Knoxville, TN"
  }
]

Service Client

In order to connect to this service, we'll use Microsoft's HttpClient library. This is a cross platform nuget package that works well with PCLs and provides a nice async interface for accessing remote web endpoints. TekConf may not be the only service that we connect to though, so we'll wrap the access to the site in a client. This segregates the TekConf service to a small corner of our apps and allows the app code to focus on the app.

Add Class to PCL -> Services/TekConfClient.cs

namespace DtoToVM.Services  
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net.Http;
    using System.Net.Http.Headers;
    using System.Threading.Tasks;
    using AutoMapper;
    using Newtonsoft.Json;
    using DtoToVM.Dtos;
    using DtoToVM.Models;

    public class TekConfClient
    {
        public async Task<List<Conference>> GetConferences ()
        {
            IEnumerable<ConferenceDto> conferenceDtos = Enumerable.Empty<ConferenceDto>();
            IEnumerable<Conference> conferences = Enumerable.Empty<Conference> ();

            using (var httpClient = CreateClient ()) {
                var response = await httpClient.GetAsync ("conferences").ConfigureAwait(false);
                if (response.IsSuccessStatusCode) {
                    var json = await response.Content.ReadAsStringAsync ().ConfigureAwait(false);
                    if (!string.IsNullOrWhiteSpace (json)) {
                        conferenceDtos = await Task.Run (() => 
                            JsonConvert.DeserializeObject<IEnumerable<ConferenceDto>>(json)
                        ).ConfigureAwait(false);

                        conferences = await Task.Run(() => 
                            Mapper.Map<IEnumerable<Conference>> (conferenceDtos)
                        ).ConfigureAwait(false);
                    }
                }
            }

            return conferences.ToList();
        }

        private const string ApiBaseAddress = "http://api.tekconf.com/v1/";
        private HttpClient CreateClient ()
        {
            var httpClient = new HttpClient 
            { 
                BaseAddress = new Uri(ApiBaseAddress)
            };

            httpClient.DefaultRequestHeaders.Accept.Clear();
            httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            return httpClient;
        }
    }
}

Data Transfer Object (DTO)

Notice that we're introducing two new classes here, the DTO and the Model. We're creating a DTO so that we can deserialize the JSON string from the api into strongly typed C# objects. We'll use the Newtonsoft JSON.net nuget package for the deserialization. This DTO will match the remote json, and therefore be in the format and naming dictated by the remote, possibly third party service.

Add Class to PCL -> Dtos/ConferenceDto.cs

namespace DtoToVM.Dtos  
{
    using System;
    public class ConferenceDto
    {
        public string Slug { get; set; }
        public string Name { get; set; }
        public DateTime Start { get; set; }
        public double[] Position { get; set; }
    }
}

Model

The model class will be in the shape and structure that we want to deal with in our app. The DTO and the model very likely will be different. In our case, the DTO has an array of doubles named position to hold the geographic location of the conference, while our Conference model has two individual properties named Latitude and Longitude, which will be easier to store in our local SQLite database.

Add Class to PCL -> Models/Conference.cs

namespace DtoToVM.Models  
{
    using System;
    using SQLite.Net.Attributes;
    public class Conference
    {
        [PrimaryKey, AutoIncrement, Column ("_id")]
        public int Id { get; set; }
        [Unique]
        public string Slug { get; set; }
        public string Name { get; set; }
        public DateTime Start { get; set; }
        public double Latitude { get; set; }
        public double Longitude { get; set; }
    }
}

Map DTO to Model

To convert from the externally defined DTO to our model, we'll use AutoMapper, which provides us an easy way to map two different objects and copy the data from one to another.

Add Class to PCL -> Bootstrapper.cs

namespace DtoToVM  
{
    using AutoMapper;
    using DtoToVM.Dtos;
    using DtoToVM.Models;

    public class Bootstrapper
    {
        public void Automapper()
        {
            Mapper.CreateMap<ConferenceDto, Conference> ()
                .ForMember(dest => dest.Latitude, opt => opt.ResolveUsing<LatitudeResolver>())
                .ForMember(dest => dest.Longitude, opt => opt.ResolveUsing<LongitudeResolver>());
        }
    }

    public class LatitudeResolver : ValueResolver<ConferenceDto, double>
    {
        protected override double ResolveCore(ConferenceDto source)
        {
            return source.Position[0];
        }
    }

    public class LongitudeResolver : ValueResolver<ConferenceDto, double>
    {
        protected override double ResolveCore(ConferenceDto source)
        {
            return source.Position[1];
        }
    }
}

View Model

At this point, we're downloading the conference data from the remote site, and transforming it into our C# model. Next, we want to create some user interface to display that data. Xamarin.Forms shines for an app like this, where we want the same UI across three platforms, and we're not going to be customizing the UI very much. In order to simplify databinding, we'll create a View Model class for the list of conferences. The View Model will implement the INotifyPropertyChanged interface to relay change events to our UI. We'll using Fody.PropertyChanged to implement the interface for us, removing the boilerplate code. See my previous post Fody.PropertyChanged + Xamarin Studio = Easy Mvvm for more information about this library.

The View Model will use the TekConfClient class to download the Conference information. It will then save the list of Conference models to a local SQLite database. Lastly, it will set the Conferences property, which our UI will bind to.

Add Class to PCL -> ViewModels/ConferencesViewModel.cs

namespace DtoToVM.ViewModels  
{
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using PropertyChanged;
    using DtoToVM.Data;
    using DtoToVM.Models;
    using DtoToVM.Services;

    [ImplementPropertyChanged]
    public class ConferencesViewModel
    {
        readonly SQLiteClient _db;

        public ConferencesViewModel ()
        {
            _db = new SQLiteClient ();
        }

        public List<Conference> Conferences { get; set; }

        public async Task GetConferences ()
        {
            await GetLocalConferences ();
            await GetRemoteConferences ();
            await GetLocalConferences ();
        }

        private async Task GetLocalConferences()
        {
            var conferences = await _db.GetConferencesAsync ();
            this.Conferences = conferences.OrderBy(x => x.Name).ToList();
        }

        private async Task GetRemoteConferences()
        {
            var remoteClient = new TekConfClient ();
            var conferences = await remoteClient.GetConferences ().ConfigureAwait(false);
            await _db.SaveAll (conferences).ConfigureAwait(false);
        }
    }
}

Save to Database

Once we download the remote conference information, we'll cache it in a local SQLite database. By using the SQLite.Net PCL, the SQLite.Net Async PCL, and the SQLite Android and SQLite iOS libraries, we are able to easily save our Conference model to a local database. The SQLite PCL enables us to write almost all of our database code in our PCL and share it across all the different platforms that we're supporting. The one piece that is not shared though is the database connection. For that, we'll create an ISQLite interface, and we'll use Xamarin.Forms DependencyService to resolve the platform specific implementation of the SQLite connection.

Add Class to PCL -> Data/SQLiteClient.cs

namespace DtoToVM.Data  
{
    using SQLite.Net.Async;

    public interface ISQLite {
        SQLiteAsyncConnection GetConnection();
    }

    using System.Collections.Generic;
    using System.Threading.Tasks;
    using SQLite.Net.Async;
    using Xamarin.Forms;
    using DtoToVM.Data;
    using DtoToVM.Models;

    public class SQLiteClient
    {
        private static readonly AsyncLock Mutex = new AsyncLock ();
        private readonly SQLiteAsyncConnection _connection;

        public SQLiteClient ()
        {
            _connection = DependencyService.Get<ISQLite> ().GetConnection ();
            CreateDatabaseAsync ();
        }

        public async Task CreateDatabaseAsync ()
        {
            using (await Mutex.LockAsync ().ConfigureAwait (false)) {
                await _connection.CreateTableAsync<Conference> ().ConfigureAwait (false);
            }
        }

        public async Task<List<Conference>> GetConferencesAsync ()
        {
            List<Conference> conferences = new List<Conference> ();
            using (await Mutex.LockAsync ().ConfigureAwait (false)) {
                conferences = await _connection.Table<Conference> ().ToListAsync ().ConfigureAwait (false);
            }

            return conferences;
        }

        public async Task Save (Conference conference)
        {
            using (await Mutex.LockAsync ().ConfigureAwait (false)) {
                // Because our conference model is being mapped from the dto,
                // we need to check the database by name, not id
                var existingConference = await _connection.Table<Conference> ()
                        .Where (x => x.Slug == conference.Slug)
                        .FirstOrDefaultAsync ();

                if (existingConference == null) {
                    await _connection.InsertAsync (conference).ConfigureAwait (false);
                } else {
                    conference.Id = existingConference.Id;
                    await _connection.UpdateAsync (conference).ConfigureAwait (false);
                }
            }
        }

        public async Task SaveAll (IEnumerable<Conference> conferences)
        {
            foreach (var conference in conferences) {
                await Save (conference);
            }
        }
    }
}

Note : Find the AsyncLock class on Scott Hanselman's Blog

SQLite Implementations

Add Class to iOS Project -> Data/SQLiteClient.cs

using Xamarin.Forms;  
using DtoToVM.iOS.Data;

[assembly: Dependency (typeof(SQLiteClient))]
namespace DtoToVM.iOS.Data  
{
    using System;
    using DtoToVM.Data;
    using SQLite.Net.Async;
    using System.IO;
    using SQLite.Net.Platform.XamarinIOS;
    using SQLite.Net;

    public class SQLiteClient : ISQLite
    {
        public SQLiteAsyncConnection GetConnection ()
        {
            var sqliteFilename = "Conferences.db3";
            var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
            var libraryPath = Path.Combine (documentsPath, "..", "Library");
            var path = Path.Combine (libraryPath, sqliteFilename);

            var platform = new SQLitePlatformIOS ();

            var connectionWithLock = new SQLiteConnectionWithLock (
                                          platform,
                                          new SQLiteConnectionString (path, true));

            var connection = new SQLiteAsyncConnection (() => connectionWithLock);

            return connection;
        }
    }
}

Add Class to Android Project -> Data/SQLiteClient.cs

using Xamarin.Forms;  
using DtoToVM.Android.Data;

[assembly: Dependency (typeof(SQLiteClient))]
namespace DtoToVM.Android.Data  
{
    using System;
    using DtoToVM.Data;
    using SQLite.Net.Async;
    using System.IO;
    using SQLite.Net.Platform.XamarinAndroid;
    using SQLite.Net;

    public class SQLiteClient : ISQLite
    {
        public SQLiteAsyncConnection GetConnection ()
        {
            var sqliteFilename = "Conferences.db3";
            var documentsPath = Environment.GetFolderPath (Environment.SpecialFolder.Personal);

            var path = Path.Combine (documentsPath, sqliteFilename);

            var platform = new SQLitePlatformAndroid ();

            var connectionWithLock = new SQLiteConnectionWithLock (
                                         platform,
                                         new SQLiteConnectionString (path, true));

            var connection = new SQLiteAsyncConnection (() => connectionWithLock);

            return connection;
        }
    }
}

Notice the use of

[assembly: Dependency (typeof(SQLiteClient))]

on each class. This will register the class in the DependencyService, and allow our PCL to resolve the dependency. Also note that on iOS, we are specifying the database path differently, so that the db3 database file is not backed up into iCloud.

Xamarin.Forms UI

The last part of the project is to create the user interface and wire everything up. We can use Xamarin.Forms to quickly create a cross platform UI and bind our list of conferences to a ListView control. Here, we'll create an instance of our ConferencesViewModel class, set the databinding to the ListView's cell template, and load the data. The key is setting the ListView's ItemsSource property to our ViewModel's Conferences property, which is implmenting the INotifyPropertyChanged events.

_conferencesListView.ItemsSource = viewModel.Conferences;  

Add Class to PCL -> Pages/ConferencesPage.cs

namespace DtoToVM.Pages  
{
    using System.Threading.Tasks;
    using Xamarin.Forms;
    using DtoToVM.ViewModels;

    public class ConferencesPage : ContentPage
    {
        ListView _conferencesListView;

        public ConferencesPage ()
        {
            this.Content = new Label { 
                HorizontalOptions = LayoutOptions.CenterAndExpand,
                VerticalOptions = LayoutOptions.CenterAndExpand
            };

            Init ();
        }

        private async Task Init ()
        {
            _conferencesListView = new ListView { 
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
            };

            var cell = new DataTemplate (typeof(TextCell));
            cell.SetBinding (TextCell.TextProperty, "Name");
            cell.SetBinding (TextCell.DetailProperty, new Binding (path: "Start", stringFormat: "{0:MM/dd/yyyy}"));

            _conferencesListView.ItemTemplate = cell;

            var viewModel = new ConferencesViewModel ();
            await viewModel.GetConferences ();
            _conferencesListView.ItemsSource = viewModel.Conferences;

            this.Content = new StackLayout {
                VerticalOptions = LayoutOptions.FillAndExpand,
                Padding = new Thickness (
                    left: 0, 
                    right: 0, 
                    bottom: 0, 
                    top: Device.OnPlatform (iOS: 20, Android: 0, WinPhone: 0)),
                Children = { 
                    _conferencesListView 
                }
            };
        }
    }
}

In just a few lines of code we were able to create a fully native app for three different platforms. We leveraged the wealth of fantastic open source PCL libraries available on Nuget to quickly connect to a remote service, download json data, convert it to a model for our app, and save it to a local database. We then wired everything up and bound the data to our UI.

This is not the only solution available to you, but it's my preferred approach and is just one of the reasons I find working with C# and Xamarin such a joy.

View the code on Github

July 01, 2014 1:57 GMT

iOS 8 Scene Kit sample in F#

Here’s an F# iOS 8 Scene Kit port of the C# code from the Xamarin blog, ported with some help from Larry O’Brien.

namespace FSHelloSceneKit
    
open System
open MonoTouch.UIKit
open MonoTouch.Foundation
open MonoTouch.SceneKit
 
type FSHelloSceneKitViewController () =
    inherit UIViewController()
   
    let CreateDiffuseLightNode (color: UIColor, position: SCNVector3, lightType: NSString): SCNNode = 
        new SCNLight ( Color = color, LightType = lightType )
        |> fun lightNode -> new SCNNode ( Light = lightNode, Position = position )
 
    override this.ViewDidLoad () =
        let scene = new SCNScene ()
     
        let view = new SCNView (this.View.Frame, Scene = scene, AutoresizingMask = UIViewAutoresizing.All, AllowsCameraControl = true)
 
        new SCNCamera (XFov = 40.0, YFov = 40.0)
        |> fun c -> new SCNNode (Camera = c, Position = new SCNVector3(0.0F, 0.0F, 40.0F))
        |> scene.RootNode.AddChildNode
 
        let material = new SCNMaterial ()
        material.Diffuse.Contents <- UIImage.FromFile ("monkey.png")
        material.Specular.Contents <- UIColor.White
 
        new SCNNode( Geometry = SCNSphere.Create(10.0F), Position = new SCNVector3(0.0F, 0.0F, 0.0F) )
        |> fun node -> node.Geometry.FirstMaterial <- material; node
        |> scene.RootNode.AddChildNode
 
        new SCNLight ( LightType = SCNLightType.Ambient, Color = UIColor.Purple)
        |> fun lightNode -> new SCNNode ( Light = lightNode )
        |> scene.RootNode.AddChildNode
 
        [|
            ( UIColor.Blue, new SCNVector3 (-40.0F, 40.0F, 60.0F) );
            ( UIColor.Yellow, new SCNVector3 (20.0F, 20.0F, -70.0F) );
            ( UIColor.Red, new SCNVector3 (20.0F, -20.0F, 40.0F) );
            ( UIColor.Green, new SCNVector3 (20.0F, -40.0F, 70.0F) )
        |]
        |> Seq.map (fun (color, pos) -> CreateDiffuseLightNode(color, pos, SCNLightType.Omni))
        |> Seq.iter scene.RootNode.AddChildNode
 
        this.View.Add(view)

You can read more about Scene Kit on the Xamarin blog.


July 01, 2014 11:23 GMT

Xamarin.Forms and MvvmCross

As promised during the Xamarin 3 webinar, I have made a small sample showing how to use Xamarin.Forms along with MvvmCross.



What I did was look at the code Stuart Lodge already had made in another private repository, and adapted this to use it with Xamarin.Forms. What it basically does is implement custom Presenter implementations, which work with the way Xamarin.Forms navigates its Pages, which is through a NavigationPage and simple Push and Pop methods. This is wrapped in a PageNavigationProvider in MvvmCross which is in turn leveraged by the custom presenter.

Right now the sample has these presenters and MvvmCross specific classes built in, but will most likely in the future be pulled out and made into a plugin, which you can use in your own applications.

So the sample itself is a very simple application, which allows you to search TMDB for movies, it then fetches similar movies based on your search query and displays them. In turn you can then press an item in the list presenting the search results and get detailed information about the movie.

The sample actually covers a lot of MvvmCross by using:

  • ViewModels
  • Services
  • Custom Presenters
  • Bindings
  • Commands
  • Converters
  • Nuget
You can get the sample on Github
July 01, 2014 9:09 GMT

Shallow: Cloning a Hook-up App in F#


If you're looking to pass superficial judgement on hot nerds in F# t-shirts, you've come to the right place.

F# is a functional programming language designed with an emphasis on data science, that can also be used to build native iOS and Android apps with Xamarin. In my experience, when people discuss F#, someone inevitably asks “F# is great for analysis, but is it good for creating user interfaces?” I created a simple Tinder clone for iOS to show that F# is actually awesome for creating UIs, and for building apps in general.

Another ‘sharp’ language?

F# is heavily inspired by OCaml, a functional language known for its pragmatic blend of functional features with a familiar object model. This inherited design decision is still bearing fruit, as F# makes it possible to build iOS and Android apps using object-oriented APIs like UIKit, while incorporating incredibly useful functional features like algebraic datatypes, pattern matching, immutability, and more. I’ll show you how I used a mix of functional and OO features to build a slick, interactive UI.

The gateway drug of functional languages

For the uninitiated, functional programmers can seem like demented wizards–they utter arcane-sounding words like functor, and get inordinately excited over tiny functions that appear to do basically nothing. Thankfully, F# can resemble a leaner version of C# when you want it to, so it’s easy to start using it. For example, here I’ve defined a type encapsulating an animation that shoots a view outside of another view:

type ShootOutAnimator(referenceView: UIView) =
    let speed = 1300.0f
    let animator = UIDynamicAnimator(referenceView)
    ...   
    member this.ShootOut(view: UIView, direction: Direction) =
        let x, y = direction.UnitVector
        let shoot = UIDynamicItemBehavior(view, AngularResistance=2.0f)
        shoot.AddLinearVelocityForItem(PointF(x * speed, y * speed), view)
        shoot.AddAngularVelocityForItem(x * 3.0f, view)
        shoot.Action <- fun () ->
            if not (referenceView.Bounds.IntersectsWith(view.Frame)) then
                animator.RemoveAllBehaviors()
                view.RemoveFromSuperview()
                shotOut.Trigger(view)
        animator.AddBehavior(shoot)

Pretty vanilla, right? Any Python, Java, or C# developer would understand at least 90% of what’s happening here.

As you become more comfortable with F#, you’ll start using functional features in your more traditionally OO code. For example, here I make an algebraic datatype for specifying directions to the ShootOutAnimator, and I define a read-only UnitVector property using type inference, pattern matching and tuples:

type Direction =
    Up | Down | Left | Right

    member this.UnitVector =
        match this with
        | Up -> (0.0f, 1.0f)
        | Down -> (0.0f, -1.0f)
        | Left -> (-1.0f, 0.0f)
        | Right -> (1.0f, 0.0f)

This lets me get the x and y components for a given screen direction like:

let (x, y) = Left.UnitVector

Finally, you can write code in a predominantly functional style. Here I create an asynchronous computation that downloads photos from an infinite stream of photo URLs, uses a higher-order memoize function to cache the results, and hides state within a closure (technically a deferred computation built with an async workflow, which is F#’s euphemism for “monad”):

let nextPhoto =
    let urls = (Seq.cycle photos).GetEnumerator()
    let getImage = memoize UIImage.FromUrl
    async {
        urls.MoveNext()
        return getImage urls.Current
    }

If you’re new to FP, you’re probably feeling a bit queasy after that last code snippet. That’s okay–the nextPhoto computation could have been implemented as a 25-line C#-style method, but I love that F# gives me such a range of expression.

These snippets come together to make this delightful interaction (full source):

I hope I’ve convinced you that compelling UIs in F# are at least possible, and that it’s a great language for gradually learning the functional concepts that are having an increasing impact on mainstream programming. If you’re still skeptical, download Xamarin, clone this app, and see for yourself! Send me an interesting pull request and I’ll mail you an F# t-shirt :smile:

Resources

June 30, 2014 6:40 GMT

Standardized Navigation Principles for Android App Development - Visual Studio Magazine Article

Navigation in mobile devices is an important consideration. If a user isn't able to navigate an app, he might quickly abandon it. Learn the navigation principles of Android to keep this from happening to you.

Mobile applications have a number of screens (Activities and Fragments) associated with them. Navigating through these is an important mechanism. There are a number of ways to provide standardized navigation in Android. This article will look at three mechanisms to provide navigation:

  1. Menus: Menus provide a common UI component for an application. The Menu APIs are used to present actions, as well as other options within an application.
  2. Navigation Drawer: The navigation drawer is a panel shown from the side of the display; it provides the user with the application's main navigation.
  3. Action Bar: The action bar provides a familiar navigation mechanism to the user across the top of the screen via an app icon, action items and action overflow.

URL: http://visualstudiomagazine.com/articles/2014/06/01/standardized-navigation-principles.aspx

Many thanks to Tomasz Cielecki

June 28, 2014 11:27 GMT

Zuckerberg and Gates

Two articles, next to each other, in my rss reader this morning. The first is about Facebook, via Marco Arment.

Scientists at Facebook have published a paper showing that they manipulated the content seen by more than 600,000 users in an attempt to determine whether this would affect their emotional state.

... And there was no need to ask study “participants” for consent, as they’d already given it by agreeing to Facebook’s terms of service in the first place.

Facebook used to be somewhat useful and interesting, to the point where the privacy stuff was bearable. Now it's filled with junk and just flat out creepy, even out-creeping Google.

The other one is from the former "Grandmaster of evil"*, Bill Gates and his wife Melinda, via The Loop:

So here is our appeal to you: As you leave Stanford, take your genius and your optimism and your empathy and go change the world in ways that will make millions of others optimistic as well.

You don’t have to rush. You have careers to launch, debts to pay, spouses to meet and marry. That’s enough for now.

But in the course of your lives, without any plan on your part, you’ll come to see suffering that will break your heart.

When it happens, and it will, don’t turn away from it; turn toward it.

That is the moment when change is born.

Gates has gone from Mr Corporate Evil to possibly one of the most prolific philanthropists in the world. The commencement speech is well worth reading.


* or so the tinfoil hat brigade in the 90's would have you believe.

June 28, 2014 3:41 GMT

Fody.PropertyChanged + Xamarin Studio = Easy Mvvm

Model-View-ViewModel (Mvvm) is a fantastic pattern when designing cross platform mobile applications. With Mvvm, we can write our ViewModels in shared code and target Xamarin.iOS, Xamarin.Android, Windows Phone, and Windows Store apps. Libraries such as Xamarin.Forms, MvvmCross, and ReactiveUI provide excellent databinding and commanding functionality.

One thing that bothers me with Mvvm is the amount of boilerplate code that is required to implement the INotifyPropertyChanged interface, which powers our databinding engine.

INotifyPropertyChanged Implementation

    using System.Runtime.CompilerServices;
    using System.ComponentModel;

    public class UserViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _firstName;
        public string FirstName {
            get { 
                return _firstName; 
            }
            set {
                if (value != _firstName) {
                    _firstName = value;
                    NotifyPropertyChanged ();
                }
            }
        }

        private string _lastName;
        public string LastName {
            get { 
                return _lastName; 
            }
            set {
                if (value != _lastName) {
                    _lastName = value;
                    NotifyPropertyChanged ();
                }
            }
        }

        private void NotifyPropertyChanged ([CallerMemberName] string propertyName = "")
        {
            if (PropertyChanged != null) {
                PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
            }
        }
    }

That's a lot of boilerplate cluttering up our code, making it harder to read and understand what this class is really trying to accomplish. The code required by the notification/databinding engine isn't adding any value to our view model and it isn't related to our application or our business logic. Ideally, we'd like to remove that boilerplate code and focus on our app.

Clean ViewModel with Auto Properties

    public class UserViewModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Luckily, there is an amazing library named Fody.PropertyChanged that we can leverage that will allow us to write only the code that we need, but rewrite the resulting assembly to implement INotifyPropertyChanged for us. All we need to do is add the PropertyChanged.Fody Nuget Package to our project, and add an attribute to our ViewModel.

ViewModel + Fody.PropertyChanged

    using PropertyChanged;

    [ImplementPropertyChanged]
    public class UserViewModel
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
    }

Out of the box, this all works just fine using Visual Studio on Windows. There are a few problems currently with Xamarin Studio though. Adding the Nuget package is successful, but the project fails to compile. Fixing these issues is easy though.

  • Add the PropertyChanged.Fody package via Nuget

    Install-Package PropertyChanged.Fody
    
  • The Nuget package adds a FodyWeavers.xml file to the project, but leaves it empty

    • Add <PropertyChanged /> to FodyWeavers.xml
<?xml version="1.0" encoding="utf-8" ?>  
<Weavers>  
    <PropertyChanged />
</Weavers>  
  • Set FodyWeavers.xml to Build Action -> Content
  • Set FodyWeavers.xml to Quick Properties -> Copy to Output Directory
  • Build

Viewing the resulting assembly in Xamarin Studio's Show Disassembly window gives the follwing result

Disassembled Code with Fody

    using System;
    using System.ComponentModel;
    using System.Runtime.CompilerServices;

    namespace TestFody
    {
        public class UserViewModelWithFody : INotifyPropertyChanged
        {
            //
            // Properties
            //
            public string FirstName {
                [CompilerGenerated]
                get {
                    return this.<FirstName>k__BackingField;
                }
                [CompilerGenerated]
                set {
                    if (string.Equals (this.<FirstName>k__BackingField, value, StringComparison.Ordinal)) {
                        return;
                    }
                    this.<FirstName>k__BackingField = value;
                    this.OnPropertyChanged ("FirstName");
                }
            }

            public string LastName {
                [CompilerGenerated]
                get {
                    return this.<LastName>k__BackingField;
                }
                [CompilerGenerated]
                set {
                    if (string.Equals (this.<LastName>k__BackingField, value, StringComparison.Ordinal)) {
                        return;
                    }
                    this.<LastName>k__BackingField = value;
                    this.OnPropertyChanged ("LastName");
                }
            }

            //
            // Methods
            //
            public virtual void OnPropertyChanged (string propertyName)
            {
                PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
                if (propertyChanged != null) {
                    propertyChanged (this, new PropertyChangedEventArgs (propertyName));
                }
            }

            //
            // Events
            //
            [field: NonSerialized]
            public event PropertyChangedEventHandler PropertyChanged;
        }
    }
June 23, 2014 7:38 GMT

How to use Xamarin.Forms Messaging Center

The goal of MVVM is to abstract away your Views from your Business Logic. This ensures great code reuse, testability, and is pretty awesome. Many MVVM Frameworks offer tools to enhance this such as data binding and dependency services to make our lives easier. These are built into Xamarin.Forms, which is awesome, but one feature less talked about is the Messaging Center. It’s entire goal is to enable ViewModels or other components to communicate with each other without having to know anything about each other besides a simple Message contract.

So for instance, let’s say you are in a master/detail setup where your MasterViewModel has a list of items and your DetailViewModel allows you to create a new item, update an item, or delete an item. When your user is on the detail page and triggers an event you need to somehow message back to your MasterViewModel that has a list of Items so the UI can react on the Master page when we navigate back.

This is where the MessagingCenter comes in. And enables anyone to “Subscribe” to message that has arguments and then enables anyone to send a message with arguments and have the Messaging Center handle the communication. This is what it looks like in image form:



So let’s say our MasterViewModel subscribes to “Update” and “AddNew” message events. It will then update it’s observable collection based on when it receives messages. Our DetailViewModel would then send a message in our SaveCommand to notify anyone that is subscribed to these specific messages:



There you have it, messaging made easy! Don’t forget to unsubscribe if you no longer wish to receive notifications.