Nick's .NET Travels

Continually looking for the yellow brick road so I can catch me a wizard....

MVX+1 Update

MvvmCross v6.0.1 was recently released. I’ve just updated both FirstDemo and TipCalc to reference v6.0.1 of MvvmCross

One of the changes that I did make to all projects is how packages are referenced. By default in Visual Studio when you reference a NuGet package it will draw in the specific version. However, by editing the csproj you can set the version to * which will mean Visual Studio will draw in the latest stable version of your referenced libraries. This is particularly convenient if you’re not in the habit of remembering to upgrade packages frequently. The downside is that you may discover one day that your app stops working, or behaves differently, thanks to a new package version being used by your application. More on this in a future post once I’ve collected my current thinking regarding continous deployment and the impact this would have on app development

MVX=0 WPF/Mac: A first MvvmCross Application (MVX+1 days of MvvmCross)

Further to some feedback on the first couple of posts in the MVX+1 series (MVX=0, MVX=0F and MVX=1), I’ve gone back and added WPF and Mac support to the FirstDemo to show just how powerful MvvmCross is. I’ll cover very briefly here how to add these project types and then I’ll be updating the TipCalc post to include the basics for WPF and Mac setup in there too.

Let’s start with WPF:

  1. Add a WPF App (.NET Framework) called FirstDemo.Wpf
    image
  2. Add a reference to MvvmCross NuGet package
  3. Add reference to FirstDemo.Core project
  4. Add ProxyMvxApplication to App.xaml.cs
    public abstract class ProxyMvxApplication : MvxApplication<MvxWpfSetup<Core.App>, Core.App> { }
  5. Update App class in both App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
  6. Remove all code in the App class (in App.xaml.cs) except for the constructor with call to InitializeComponent
    public App()
    {
         InitializeComponent();
    }
  7. Update MainWindow in both MainWindow.xaml and MainWindow.xaml.cs to inherit from MvxWindow
  8. Create Views folder
  9. Add new User Control (WPF) called FirstView.xaml
  10. Update FirstView in both FirstView.xaml and FirstView.xaml.cs to inherit from MvxWpfView
  11. Add XAML to FirstView.xaml
    <StackPanel Margin="12,12,12,12">
         <TextBox Text="{Binding FirstName, Mode=TwoWay}"></TextBox>
         <TextBox Text="{Binding LastName, Mode=TwoWay}"></TextBox>
         <TextBlock Text="{Binding FullName}"></TextBlock>
    </StackPanel>

You should now be able to build and run the WPF application – notice how little code we have to add/change in order to get MvvmCross to work!

Next up is Mac which at the moment can only be done on a Mac (almost no surprises there – it’s the same as not being able to do UWP development on a Mac I guess):

  1. Add a Cocoa App called FirstDemo.Mac
    image
  2. Add a reference to MvvmCross NuGet package
  3. Add reference to FirstDemo.Core project
  4. At this point I would recommend unloading your project, editing the csproj file manually to removed the legacy nuget reference and add the following ItemGroup. Also remove the reference to package.config, remove the actual package.config file and delete both bin and obj folders. Reload the Mac project and force a rebuild.
    <ItemGroup>
       <PackageReference Include="MvvmCross" Version="6.0.0" />
    </ItemGroup>
  5. Update AppDelegate to inherit from MvxApplicationDelegate
    [Register("AppDelegate")]
    public class AppDelegate: MvxApplicationDelegate<MvxMacSetup<App>, App>
    {
         public override void DidFinishLaunching(NSNotification notification)
         {
             MvxMacSetupSingleton.EnsureSingletonAvailable(this, MainWindow).EnsureInitialized();
             RunAppStart();
            // Due to a bug, do not call base DidFinishLaunching
             //base.DidFinishLaunching(notification);
         }
    }
    Note: There is a bug at the moment where if you don’t override DidFinishLaunching the application will crash on startup
  6. Open main.storyboard – this should open the storyboard in the XCode designer
  7. Select the existing view controller and set the Class and Storyboard ID to FirstView
    image
  8. Make sure the FirstView name change has been saved; return to VS for Mac and confirm that files FirstView.cs and FirstView.designer.cs have been created. If these have not been created, I would suggest doing a rebuild of your project to make sure the changes to the storyboard have been processed and the appropriate designer files created.
  9. From the Object Library drag two TextField and a Label across onto the design surface
    image
  10. Open Project navigator and make sure you have FirstView.h and FirstView.m. If you don’t I would suggest closing both XCode and VS for Mac, deleting the bin and obj folder from within the FirstDemo.Mac folder and reopening the solution in VS for Mac. Rebuild the Mac project and then launch XCode by double clicking on main.storyboard.
    image
  11. Hide both Project navigator (left pane) and Utilities (right pane) and show the Assistant Editor (the icon button that has linked circles in top right corner of XCode)
  12. From the navigator bar in the Assistant Editor, select Manual –> FirstView.Mac –> FirstView.h
    image
  13. Right-click on the first TextField
    image
  14. Click and drag the circle next to New Referencing Outlet across onto the FirstView.h immediately before the @End. When you release, you should be prompted to complete information about the new Outlet where you can specify the Name, textEditFirst, which will be the name of the backing variable you’ll be able to use to reference the TextField in code
    image
  15. Repeat the previous step for the second TextField, textEditSecond, and the Label, labelFull.
  16. Update FirstView.cs to add the MvxFromStoryboard attribute, change the base class to MvxViewController and add data binding using the CreateBindingSet extension
    [MvxFromStoryboard("Main")]
    public partial class FirstView : MvxViewController<FirstViewModel>
    {
         public FirstView(IntPtr handle) : base(handle)
         {
         }
  17.     public override void ViewDidLoad()
         {
             base.ViewDidLoad();
             var set = this.CreateBindingSet<FirstView, FirstViewModel>();
             set.Bind(textEditFirst).To(vm => vm.FirstName);
             set.Bind(textEditSecond).To(vm => vm.LastName);
             set.Bind(labelFull).To(vm => vm.FullName);
             set.Apply();
         }
    }

And there you have it – build and run your Mac FirstDemo application

    MvvmCross: Initialize method on the first view model

    An issue was raised on MvvmCross following the release of v6 where applications were breaking because they have async code in the Initialize method of the first view model. Changes in v6 mean that the first view model is effectively loaded synchronously. This change was made because applications should not do heavy lifting before displaying the first view of their application as there are platform requirements that will cause the application to terminate if it doesn’t display the first view within the appropriate time window. This change means that any code that attempts to jump to a different thread (even something like Task.Delay) will cause the fist view of the application to break.

    In some scenarios this doesn’t make sense – for example if you have a splash screen Activity on Android, the first navigation can be done asynchronously because you already have a view being displayed on the screen. Here I’m going to use a simple example to demonstrate how to resolve this issue – you should only use this if you are using a splash screen for the first view of your application.

    Let’s start by breaking our application by adding the following to our first view model:

    public override async Task Initialize()
    {
         await Task.Delay(2000);
         await base.Initialize();
    }

    If you make this change and attempt to run your application you’ll see a black screen (on Android – and I’m using Android because we typically have a splash Activity such as in my earlier post).

    Next we’re going to fix this by overriding the MvxAppStart class to make the first navigation asynchronous:

    public class CustomMvxAppStart<TViewModel> : MvxAppStart<TViewModel>
         where TViewModel : IMvxViewModel
    {
         public CustomMvxAppStart(IMvxApplication application, IMvxNavigationService navigationService) : base(application, navigationService)
         {
         }

        protected override void NavigateToFirstViewModel(object hint)
         {
             NavigationService.Navigate<TViewModel>();
         }
    }

    Note that it’s the bold line that we’ve changed from the built in MvxAppStart class where we call NavigationService.Navigate<TViewModel>().GetAwaiter().GetResult(); which forces the navigation to be done synchronously.

    We now need to make sure that our CustomMvxAppStart is used. To do this we just need to change a single line in the App.cs to use RegisterCustomAppStart instead of RegisterAppStart

    RegisterCustomAppStart<CustomMvxAppStart<FirstViewModel>>();

    And we’re done – running the application now will allow the application to load successfully.

    MVX=1: TipCalc - a second example - adding IoC and the Xamarin Android Designer (MVX+1 days of MvvmCross)

    Following on from the first post in the MVX+1 series, in this post we’ll create a basic Tip Calculator (mirroring the original post from the N+1 series). However, in this case the first section is a more detailed set of instructions on how to get the basics of all three platforms setup with MvvmCross. Going forward we’ll use this as a starting point so that we don’t need to cover over this in each subsequent post.

    Source code: https://github.com/nickrandolph/MvxPlus1DaysOfMvvmCross/tree/master/Mvx-01-TipCalc

    Getting Started Instructions (Native Apps)

    Note: In this case the name of the application is TipCalc but these instructions can be followed to get any new project started by simply replacing TipCalc with the name of your project.

    1. Create a the new solution by creating a new Class Library (.NET Standard) with the project name set to TipCalc.Core and the solution name to just TipCalc.
    2. Add a new project based on the Blank App (Universal Windows) project template called TipCalc.Uwp (make sure that the Minimum and Target versions are set to at least the Fall Creators Update)
    3. Add a new project based on the Android App (Xamarin) project template called TipCalc.Droid (use the Blank app template)
    4. Add a new project based on the iOS App (Xamarin) project template called TipCalc.iOS (use the Blank app template)
    5. Add a reference to MvvmCross NuGet package (v6.0.0 at time of writing to all four projects)
    6. TipCalc.Uwp: Update NuGet package Microsoft.NETCore.UniversalWindowsPlatform to the latest stable version (6.0.8 at time of writing)
    7. TipCalc.Droid: Update the Android version to Use Latest Platform (Project Properties –> Application –> Target Framework)
    8. TipCalc.Droid: Update Xamarin.Android.Support.Design to latest stable version (27.0.2 at time of writing)
    9. TipCalc.Droid: Add a reference to MvvmCross.Droid.Support.V7.AppCompat package
    10. TipCalc.iOS: Unload project; delete packages.config; edit TipCalc.iOS.csproj and add the following ItemGroup
      <ItemGroup>
         <PackageReference Include="MvvmCross" Version="6.0.0" />
      </ItemGroup>
    11. Add a reference to TipCalc.Core to each of the three head projects (ie TipCalc.Uwp, TipCalc.Droid and TipCalc.iOS)
    12. TipCalc.Core: Rename the default Class1.cs to App.cs, and allow Visual Studio to rename class to App
    13. TipCalc.Core: Change the App class to inherit from MvxApplication
    14. TipCalc.Core: Add a folder, ViewModels, and add a class called FirstViewModel.
    15. TipCalc.Core: Change FirstViewModel to inherit from MvxViewModel
    16. TipCalc.Core: Override Initialize method in App to register services and set startup view model to FirstViewModel
      public override void Initialize()
      {
           CreatableTypes()
                   .EndingWith("Service")
                   .AsInterfaces()
                   .RegisterAsLazySingleton();
           RegisterAppStart<FirstViewModel>();
      }
    17. TipCalc.Uwp: Add a help class ProxyMvxApplication
      public abstract class ProxyMvxApplication: MvxApplication<MvxWindowsSetup<Core.App>, Core.App> { }
    18. TipCalc.Uwp: Change App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
    19. TipCalc.Uwp: Remove all code in App.xaml.cs other than the constructor which should contain a single call to InitializeComponent
    20. TipCalc.Uwp: Delete MainPage.xaml and MainPage.xaml.cs
    21. TipCalc.Uwp: Add a Views folder, and  add a FirstView based on the Blank Page template
    22. TipCalc.Uwp: Change FirstView.xaml and FirstView.xaml.cs to inherit from MvxWindowsPage
    23. TipCalc.Droid: Add a new class, MainApplication, that inherits from MvxAppCompatApplication
    24. [Application]
      public class MainApplication : MvxAppCompatApplication<MvxAppCompatSetup<App>, App>
      {
           public MainApplication(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
           {
           }
      }

    25. TipCalc.Droid: Rename MainActivity.cs to SplashScreen.cs and let Visual Studio rename the class
    26. TipCalc.Droid: Rename activity_main.axml to SplashScreen.axml, and adjust layout to indicate application loading
    27. TipCalc.Droid: Adjust SplashScreen class to inherit from MvxSplashScreenAppCompatActivity and set NoHistory to true (since we don’t want the user to be able to press the back button and go back to the splash screen)

      [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true, NoHistory = true)]
      public class SplashScreen : MvxSplashScreenAppCompatActivity

    28. TipCalc.Droid: Add a folder, Views, and add a new Activity, FirstView.c
    29. [Activity(Label = "FirstView")]
      public class FirstView : MvxAppCompatActivity<FirstViewModel>
      {
           protected override void OnCreate(Bundle bundle)
           {
               base.OnCreate(bundle);

              SetContentView(Resource.Layout.FirstView);
           }
      }

    30. TipCalc.Droid: Add a new Android Layout to the Resources/Layout folder, FirstView.axml
    31. TipCalc.Droid: You may run into an error: “error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute.” If you do, you just need to Add Reference to Mono.Android.Export (search in the Add Reference dialog).
    32. TipCalc.iOS: Update AppDelegate class to inherit from MvxApplicationDelegate, and remove the default code.
      [Register("AppDelegate")]
      public class AppDelegate : MvxApplicationDelegate<MvxIosSetup<App>, App>
      {
      }
    33. TipCalc.iOS: Add an Empty Storyboard, called Main.storyboard, to the root of the project
    34. TipCalc.iOS: Add a ViewController to the Main.storyboard using the designer and set the Class and Storyboard ID to FirstView (also make sure the “User Storyboard ID” checkbox is set to true)
    35. TipCalc.iOS: Move the generated FirstView.cs and FirstView.designer.cs files (from the previous step) into a new folder called Views, and adjust the namespace of the FirstView class to FirstView.iOS.Views
    36. TipCalc.iOS: Update the FirstView class to inherit from MvxViewController
      [MvxFromStoryboard("Main")]
      public partial class FirstView : MvxViewController<FirstViewModel>


    Now to actually build out the Tip Calculator. Rather than embed the calculation logic into our view model, we’re going to abstract it out into a service. To do this we’ll make use of the IoC container made available by MvvmCross. We’ll register a CalculationService which will be injected into our view model constructor.

    Let’s continue our development of the Tip Calculator in TipCalc.Core:

    1. Add a folder called Services
    2. Add an interface ICalculationService into the Services folder
      public interface ICalculationService
      {
           double Tip(double subTotal, double generosity);
      }
    3. Add a class, CalculationService, which implements ICalculationService, again into the Services folder
      public class CalculationService : ICalculationService
      {
           public double Tip(double subTotal, double generosity)
           {
               return subTotal * generosity / 100.0;
           }
      }

    4. Add a constructor to the FirstViewModel which accepts an ICalculationService parameter
    5. private readonly ICalculationService _calculationService;
      public FirstViewModel(ICalculationService calculationService)
      {
           _calculationService = calculationService;
      }

    6. Add properties for SubTotal, Generosity, Tip and Total. Each property should take the following form where SetProperty is called within the setter
      private double _subTotal;
      public double SubTotal
      {
           get { return _subTotal; }
           set { SetProperty(ref _subTotal, value); }
      }
    7. Add a Recalc method which will invoke the Tip method on the ICalculationService
      private void Recalc()
      {
           Tip = _calculationService.Tip(SubTotal, Generosity);
           Total = SubTotal + Tip;
      }
    8. Add a call to Recalc into the setter for both SubTotal and Generosity
    9. Set some initial values for the SubTotal and Generosity (if you use the property setters, rather than setting the fields, the Recalc method will be invoked)

    That’s it for the core logic for the application. Now we just need to wire up the UI for each platform.

    One thing that’s worth noting is that in step 16 of the original setup where the Initialize method is overridden, there is logic in the Initialize method to interrogate the current assembly looking for all classes that end in Service and register them, based on their interface, with the MvvmCross IoC container – this is how MvvmCross knows about the implementation of the ICalculationService which is used when instantiating the FirstViewModel.

    Let’s built out the UWP interface in TipCalc.Uwp:

    1. Add the following XAML inside the existing Grid element:
      <StackPanel>
           <TextBlock Text="SubTotal"/>
           <TextBox Text="{Binding SubTotal, Mode=TwoWay}"/>
           <TextBlock Text="How generous?"/>
           <Slider Value="{Binding Generosity, Mode=TwoWay}"
                   Minimum="0"
                   Maximum="100"/>
           <TextBlock Text="Tip:"/>
           <TextBlock Text="{Binding Tip}"/>
           <TextBlock Text="SubTotal:"/>
           <TextBlock Text="{Binding Total}"/>
      </StackPanel>

    That’s the UWP interface done – four elements (with TextBlock headings): TextBox and Slider for inputting SubTotal and Generosity using two-way data binding, and two TextBlock for outputting the Tip and Total amounts.

    Now let’s do Android:

    1. Add the following namespace declaration to FirstView.axml
      xmlns:local="http://schemas.android.com/apk/res-auto"
    2. Add the following xml to FirstView.axml
      <TextView
           android:text="SubTotal"
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:id="@+id/textView1" />
      <EditText
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:id="@+id/editText1"
           local:MvxBind="Text SubTotal" />
      <TextView
           android:text="Generosity"
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:id="@+id/textView2" />
      <SeekBar
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           local:MvxBind="Progress Generosity"
           android:id="@+id/seekBar1" />
      <TextView
           android:text="Tip"
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:id="@+id/textView3" />
      <TextView
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           local:MvxBind="Text Tip"
           android:id="@+id/textView4" />
      <TextView
           android:text="Total"
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           android:id="@+id/textView5" />
      <TextView
           android:textAppearance="?android:attr/textAppearanceMedium"
           android:layout_width="fill_parent"
           android:layout_height="wrap_content"
           local:MvxBind="Text Total"
           android:id="@+id/textView6" />

    In this case we’re leveraging the xml extensions offered by MvvmCross in order to do the data binding using the MvxBind syntax.

    Finally, let’s do iOS:

    1. Add the following code to the FirstView.cs
      public override void ViewDidLoad()
      {
           base.ViewDidLoad();
    2.     // Perform any additional setup after loading the view
           var label = new UILabel(new RectangleF(10, 0, 300, 40));
           label.Text = "SubTotal";
           Add(label);

          var subTotalTextField = new UITextField(new RectangleF(10, 40, 300, 40));
           Add(subTotalTextField);

          var label2 = new UILabel(new RectangleF(10, 80, 300, 40));
           label2.Text = "Generosity?";
           Add(label2);

          var slider = new UISlider(new RectangleF(10, 120, 300, 40));
           slider.MinValue = 0;
           slider.MaxValue = 100;
           Add(slider);

          var label3 = new UILabel(new RectangleF(10, 160, 300, 40));
           label3.Text = "Tip";
           Add(label3);

          var tipLabel = new UILabel(new RectangleF(10, 200, 300, 40));
           Add(tipLabel);

          var label4 = new UILabel(new RectangleF(10, 240, 300, 40));
           label4.Text = "Total";
           Add(label4);

          var totalLabel = new UILabel(new RectangleF(10, 280, 300, 40));
           Add(totalLabel);

         var set = this.CreateBindingSet<FirstView, FirstViewModel>();
           set.Bind(subTotalTextField).To(vm => vm.SubTotal);
           set.Bind(slider).To(vm => vm.Generosity);
           set.Bind(tipLabel).To(vm => vm.Tip);
           set.Bind(totalLabel).To(vm => vm.Total);
           set.Apply();

      }

    In this case for iOS we again make use of the data binding support provided by MvvmCross by using the CreateBindingSet method, followed by a call to Bind for each element property we want to bind, and then finally a call to Apply to complete the setup of data binding.

    And that’s it – a Tip Calculator for all three platforms.

    MVX=0F Side Note: Adding a Splash Screen

    I received some feedback on my previous post on setting up MvvmCross for Xamarin.Forms, asking how to add a splash screen to the Android Forms application. In the post MVX=0 I converted the MainActivity that comes as part of the standard Xamarin Android project into a SplashScreen but when it came to the Android project for Xamarin.Forms I left it without a splash screen.

    Luckily adding a splash screen is really easy, so let’s add one to the Forms.Droid project:

    1. Copy the SplashScreen.axml from the /Resources/layout folder in the FirstDemo.Droid project into the /Resources/layout folder in the Forms.Droid project
    2. Remove “MainLauncher = true” from the Activity attribute on the MainActivity
    3. Change the MainActivity inheritance:
      public class MainActivity : MvxFormsAppCompatActivity<MainViewModel>
    4. Add a new class, SplashScreen.cs:
      [Activity(Label = "FirstDemo.Forms.Splash", Theme = "@style/MainTheme", MainLauncher = true, NoHistory = true)]
      public class SplashScreen : MvxFormsSplashScreenAppCompatActivity<MvxFormsAndroidSetup<Core.App, App>, Core.App, App>
      {
           public SplashScreen() : base(Resource.Layout.SplashScreen)
           {
           }
    5.     protected override void RunAppStart(Bundle bundle)
           {
               StartActivity(typeof(MainActivity));
               base.RunAppStart(bundle);
           }
      }

    And there you have it – the Android Xamarin.Forms project will launch with a splash screen before redirecting to the MainActivity which will host the Xamarin.Forms content.

    Declarative C# as an alternative to XAML

    Yesterday I had one of those moment where one minute you’re super opinionated on something, only for someone to point out how things have changed and that you should re-evaluate your position – As much as I have my personal preferences on a lot of developer related topics, I try to listen to those around me and look at why they’re doing things their way, and whether I can adapt/learn/extend what I’m doing.

    Yesterday in my post talking about CSS in Xamarin.Forms I made a comment that developers building for Xamarin.Forms should be using XAML and “if you’re doing it in code, you’re wasting everyone’s time”. Almost immediately after posting this I was following a related twitter thread (Adam’s thread on whether XAML is holding Xamarin.Forms back) and I saw a link to the work that Vincent has been doing on using declarative c# instead of XAML. This started with a discussion on the Xamarin forums: https://forums.xamarin.com/discussion/123771/using-declarative-style-c-instead-of-xaml-should-xamarin-redirect-xaml-efforts-elsewhere? Then Vincent provided a link to his repo on Github: https://github.com/VincentH-Net/CSharpForMarkup

    My issue with using C# to define layout is that out of the box it’s very difficult to construct layouts without it making it look like a jumbled mess – XAML makes the layout very clean and easy for any XAML developer to easily grok what’s going on. However, what Vincent has done is provide some simple extensions that make it possible to define the layout in a very fluent manner.

    Whilst I still prefer, and would recommend using XAML, if you must use C# to define layouts, you should look at the work Vincent has done and perhaps leverage it in your code. Furthermore I’d love to see some metrics on whether there is a noticeable performance gain in using C# versus compiled XAML, and how to handle styles, templates and other resources in code.

    Xamarin Forms gets CSS to pander to web developers

    I just finished reading a good post by fellow Microsoft MVP, Sam Basu, looking at how to use CSS for styling web development. Since becoming aware of the intent to add CSS as a styling option with Xamarin Forms I’ve been an advocate against it, not because I’m “not a web guy” but because the platform doesn’t need options. Xamarin Forms is a great platform and one that I’ve been talking, blogging and working with since it was created; it’s not perfect but it’s incredibly powerful in how quickly cross-platform applications can be generated. What it does not need is a second alternative for styling.

    In talking with the product team and other Xamarin Forms developers I’m always keen to understand their opinions, so I decided that I’d review Sam’s list of CSS benefits and try to boil them down into why I think the decision was made to add CSS. My summary of the list it comes down to (I’ve discounted the other comments because they’re just statements, not really benefits of CSS over XAML styling):

    - The developer ecosystem is inundated with web developers (ie people who know and understand CSS) so let’s give them a technology they’re familiar with (without having to learn anything new)

    - CSS is less verbose

    - CSS offers additional styling inheritance

    -  CSS can be shared between web and Xamarin Forms applications

    Let me leave the first point for a second – I promise I’ll come back to it. The second point regarding CSS being less verbose is a bit irrelevant since intellisense/autocomplete makes writing XAML styles super quick; XAML styles are then compiled and so don’t need to be parsed in the way CSS does. I have to admit, one of the only benefits I see of using CSS is around styling inheritance and referencing – this has always been a limitation of XAML styles and one that I would love to see a fix for, rather than cobbling some other styling alternative. The last point regarding sharing CSS between web and Forms might be nice in theory but as we’ve seen say across Phone, Windows, Xbox, the reality is that most of the styling needs to be adjusted per platform anyhow, so the benefits are marginal at best.

    The article goes on to talk about some caveats – I’ll rephrase this as “Here are the reasons you should never use CSS in you Xamarin Forms application”:

    - XAML styling is, and I’m guessing, will continue to be the primary way to do styling in Xamarin Forms – anything else will be built on top of this meaning that all new features will come later, if at all, to CSS

    - There are some limitations on what CSS can do, even today – do you think this will get addressed any time soon? I wouldn’t be betting the future of any project on these getting addressed in the short term, if ever.

    - CSS is parsed – Xamarin/Xamarin Forms adds enough overhead as it is, do you really want to slow down your mobile apps further. Just on this note, please make sure you optimise your apps, leveraging XAML compilation

    Ok so I mentioned I’d come back to the first benefit of using CSS which is that it’s a familiar technology for web developers – the reality is that Xamarin.Forms is for building mobile applications and unless you’ve come from a background of building SPAs with offline capabilities (such as building a PWA), chances are you’re going to need to learn a bunch more than just XAML syntax. Furthermore, if you’re going to be building with Xamarin.Forms you need to be using XAML to layout your pages (if you’re doing it in code, you’re wasting everyone’s time), so why wouldn’t you use XAML styling too.

    Now, do I think that XAML styling is perfect? – it is definitely not. The lack of even simple things like multiple inheritance, and in the case of Xamarin.Forms, basic control templates for the standard controls, are annoyances and need to be fixed. I think there is an opportunity to learn from CSS and adapt it to improve XAML across the board. Do I think this is a good enough reason for adding CSS? NO, I repeat NO – you can’t imagine the resource drain that CSS will have on the Xamarin.Forms product team (bugs, feature requests, support for new features).

    Going forward I’d like Xamarin.Forms to focus on core requirements with a view to “bringing back the magic”.

    MVX=0F: A first MvvmCross Application (MVX+1 days of MvvmCross)

    Updated 16/4/2018: Reference to MvvmCross have been updated to v6.0.0

    One of the awesome things about MvvmCross is that you can take the exact same set of ViewModels that you used for your UWP, iOS, Android applications and use them in a Xamarin Forms application. As we go through the MVX+1 series, I’ll make some space for talking about Xamarin Forms as well.

    In this post we're going to extent what we started in the previous post by adding a Xamarin Forms interface – this means creating new head projects for iOS, Android and UWP too. All up we’re adding four new projects but fear not, most of the heavy lifting is done by Visual Studio:

    Into our existing solution we’re going to add a new Xamarin Forms project:

    1. Add a new Mobile App (Xamarin.Forms) project called FirstDemo.Forms
      image_thumb1_thumb
    2. When prompted, select Blank App, make sure all three Platforms are checked and make sure you select the .NET Standard option (Do NOT use the Share Project option).
      image_thumb3_thumb
    3. Upgrade the Xamarin.Forms NuGet to latest for all four Forms projects (at time of writing is 2.5.1.444934)
    4. Add MvvmCross NuGet Package to all Forms projects (Forms, Forms.iOS, Forms.Android and Forms.UWP)
    5. Add MvvmCross.Forms NuGet Package to all Forms projects (Forms, Forms.iOS, Forms.Android and Forms.UWP)

    Note: You may need to upgrade to latest NuGet packages for all Forms projects before you can add references to the MvvmCross packages.

    Update the FirstDemo.Forms project

    1. Remove all code in App class except for constructor with a call to InitializeComponent
    2. Create Views folder
    3. Move MainPage into Views folder and rename to FirstView
    4. Adjust FirstView.xaml and FirstView.xaml.cs to change class name to FirstView and to make it inherit from MvxContentPage
    5. Add two Entry and a Label with data binding to FirstView.xaml


    Update the FirstDemo.Forms.Uwp project

    1. Update Microsoft.NETCore.UniversalWindowsPlatform (v6.0.8 at time of writing)
    2. Add reference to FirstDemo.Core
    3. Change MainPage to inherit from MvxFormsWindowsPage
    4. Remove all code other than the InitializeComponent method call in the constructor of MainPage
    5. Add ProxyMvxApplication
      public abstract class ProxyMvxApplication : MvxWindowsApplication<MvxFormsWindowsSetup<Core.App, FirstDemo.Forms.App>, Core.App, FirstDemo.Forms.App, MainPage>
    6. Change App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
    7. Remove all code other than the constructor, with a single call to InitializeComponent, in App.xaml.cs

    Update the FirstDemo.Forms.Android project

    Note (1): If you run into the following error, you may need to rename your project. In this case we renamed it to Forms.Droid (as well as the folder the project resides in)
    1>C:\Program Files (x86)\Microsoft Visual Studio\Preview\Enterprise\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets(2088,3): error MSB4018: System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

    Note (2): If you’re using the preview build of Visual Studio, you may run into an error: “error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute.” If you do, you just need to Add Reference to Mono.Android.Export (search in the Add Reference dialog).

    1. Change Forms.Android project to target latest Android SDK (v8.1 at time of writing)
    2. Upgrade Xamarin.Android.Support.* to latest for the Forms.Android project
    3. Add reference to FirstDemo.Core
    4. Change MainActivity inheritance, remove code except for a constructor:
      public class MainActivity : MvxFormsAppCompatActivity<MvxFormsAndroidSetup<Core.App, App>, Core.App, App>
      {
      }

    Update the FirstDemo.Forms.iOS project

    1. Add reference to FirstDemo.Core
    2. Changed inheritance of AppDelegate
      public partial class AppDelegate : MvxFormsApplicationDelegate<MvxFormsIosSetup<Core.App, FirstDemo.Forms.App>, Core.App, FirstDemo.Forms.App>

    And there you have it – you should be able to build and run all three Forms projects utilising the same view models that the non-Forms projects used

    MVX=0 : A first MvvmCross Application (MVX+1 days of MvvmCross)

    [Repost: Apologies for those who have already read this but there were some issues with the link generated for the previous post, so I’ve reposted it]

    Updated 16/4/2018: Reference to MvvmCross have been updated to v6.0.0

    Yes, this is going to be a sequence of posts reworking the infamous N+1 series that Stuart Lodge did starting almost exactly 5 years ago. As we approach the 5 year anniversary of these posts I thought it only fitting to cover this series again as a way of introducing MvvmCross v6 which will be released very shortly has just been released. Unlike the original series that were YouTube videos accompanied by blog posts, this series will only contain the posts, mainly because I find generating videos to be time consuming. Anyhow, here goes:

    We’ll start by creating a Blank Solution.

    image_thumb4_thumb

    Into the solution we’ll add a Core Library that will contain an App class and our first ViewModel:

    1. Add a Class Library (.NET Standard) called FirstDemo.Core
      image_thumb3_thumb
    2. Add a reference to MvvmCross NuGet package (v6.0.0-beta.8 v6.0.0 at time of writing)
    3. Rename the default Class1.cs to App.cs, and allow Visual Studio to rename class to App
    4. Change App to inherit from MvxApplication
    5. Add a folder, ViewModels, and add a class called FirstViewModel.
    6. Change FirstViewModel to inherit from MvxViewModel
    7. Add logic to FirstViewModel to include FirstName, LastName and a calculated FullName
    8. Override Initialize method in App to call RegisterAppStart, specifying FirstViewModel as the startup ViewModel

    Let’s start with a Universal Windows Platform UI:

    1. Add a Blank App (Universal Windows) called FirstDemo.Uwp
      image_thumb6_thumb
    2. Make sure Minimum and Target versions are set to at least the Fall Creators Update so that it supports .NET Standard 2.0
      image_thumb8_thumb
    3. Update NuGet package Microsoft.NETCore.UniversalWindowsPlatform to the latest stable version (6.0.8 at time of writing)
    4. Add a reference to MvvmCross NuGet package
    5. Add reference to FirstDemo.Core project
    6. Add a help class ProxyMvxApplication to the FirstDemo.Uwp project – this is a proxy class to compensate for the lack of generics support in XAML
    7. public abstract class ProxyMvxApplication: MvxApplication<MvxWindowsSetup<Core.App>, Core.App> { }

    8. Change App.xaml and App.xaml.cs to inherit from ProxyMvxApplication
    9. Remove all code in App.xaml.cs other than the constructor which should contain a single call to InitializeComponent
    10. Delete MainPage.xaml and MainPage.xaml.cs
    11. Add a Views folder, and  add a FirstView based on the Blank XAML page template
    12. Change FirstView.xaml and FirstView.xaml.cs to inherit from MvxWindowsPage
    13. Add some TextBoxes and a TextBlock to the FirstView, complete with databinding
    14. Hit F5 and run the application (you may have to set the FirstDemo.Uwp project as the startup project and make sure it’s set to build and deploy using the Configuration Manager)

    Next let’s add the Android UI:

    1. Add a Android App (Xamarin) called FirstDemo.Droid
      image_thumb10_thumb
    2. Select the Blank App template, and the minimum Android version
    3. Update the Xamarin.Android.Support.Design NuGet package (at time of writing the latest is 27.0.2)
    4. Update the Android version to Use Latest Platform
      image_thumb12_thumb
    5. Add a reference to MvvmCross NuGet package
    6. Add a reference to MvvmCross.Droid.Support.V7.AppCompat package
    7. Add reference to FirstDemo.Core project
    8. Add a new class, MainApplication, that inherits from MvxAppCompatApplication
      public class MainApplication : MvxAppCompatApplication<MvxAppCompatSetup<App>, App>
    9. Rename MainActivity.cs to SplashScreen.cs and let Visual Studio rename the class
    10. Rename activity_main.axml to SplashScreen.axml, and adjust layout to indicate application loading
    11. Adjust SplashScreen class to inherit from MvxSplashScreenAppCompatActivity and set NoHistory to true (since we don’t want the user to be able to press the back button and go back to the splash screen)
    12. [Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true, NoHistory = true)]
      public class SplashScreen : MvxSplashScreenAppCompatActivity

    13. Add a folder, Views, and add a new Activity, FirstView.cs
      1. Add a new Android Layout to the Resources/Layout folder, FirstView.axml, with a couple of EditText and a TextView, all data bound using MvxBind
      2. You may run into an error: “error XA4210: You need to add a reference to Mono.Android.Export.dll when you use ExportAttribute or ExportFieldAttribute.” If you do, you just need to Add Reference to Mono.Android.Export (search in the Add Reference dialog).
      3. Set the startup project to be FirstDemo.Droid and press F5 to run the application

      Lastly, let’s add the iOS UI:

      1. Add an iOS App (Xamarin) called FirstDemo.iOS
        image_thumb2_thumb
      2. Select the Blank App template, Universal devices support and Minimum iOS Version of 11.2
        1. Add a reference to MvvmCross NuGet package
          1. Add reference to FirstDemo.Core project
          2. Update AppDelegate class to inherit from MvxApplicationDelegate
            public class AppDelegate : MvxApplicationDelegate<MvxIosSetup<App>, App>
          3. Add an Empty Storyboard, called Main.storyboard, to the root of the project
          4. Add a ViewController to the Main.storyboard using the designer and set the Class and Storyboard ID to FirstView (also make sure the “User Storyboard ID” checkbox is set to true)
          5. Move the generated FirstView.cs and FirstView.designer.cs files (from the previous step) into a new folder called Views, and adjust the namespace of the FirstView class to FirstView.iOS.Views
          6. Add two UITextField and a UILabel to the FirstView ViewController using the Main.storyboard designer (make sure each element has a Name set so it can be referenced from code)
          7. Update the FirstView class to inherit from MvxViewController
            [MvxFromStoryboard("Main")]
            public partial class FirstView : MvxViewController<FirstViewModel>
          8. Add logic to FirstView to enable databinding using the CreateBindingSet extension method
          9. Set the startup project to be FirstDemo.Droid and press F5 to run the application
            Update 16/4/2018: For some reason the iOS App (Xamarin) project template still uses a package.config. During the update to the stable v6.0.0 package the package.config file in FirstDemo.iOS was removed, the reference in FirstDemo.iOS.csproj to MvvmCross was manually removed and the following ItemGroup added:
            <ItemGroup>
               <PackageReference Include="MvvmCross" Version="6.0.0" />
            </ItemGroup>

          The final code is available at https://github.com/nickrandolph/MvxPlus1DaysOfMvvmCross/tree/master/Mvx-00-FirstDemo

          To get this to work I would suggest running the latest Visual Studio for Mac or PC. Hit me up on Twitter or Slack if you have any issues following the steps or running the samples.

          Progressive Web Apps–Are these a “thing” yet?

          Maximiliano Firtman has a great post that discusses the current state of play of Progressive Web Apps (aka PWAs). For me the stand outs are:

          - iOS hides the “Add to Homescreen” option within the Share extension

          - On iOS the ability to Add to homescreen isn’t available when using Edge or Chrome, despite the Share extension being a common across applications.

          - Lack of push notifications is a major annoyance from a user perspective – After installing iOS 11.3 I went and added the PWA version of Twitter (just go to https://mobile.twitter.com and add to homescreen). The app works great but the lack of any form of notifications is just crippling and means I now miss messages until I get prompted to go into the Twitter app. This alone is a reason for me to install the store version of the app.

          - PWAs still only get a limited cache, with no option to extend it with user consent, which is hardly enough to cache the static resources for a good responsive website, let alone provide offline data access

          - Windows support is still via an app coming from the store

          The upshot of this is that whilst Google is doing a great job in advocating for PWAs, the reality is that they’re still not ready for the prime time.

          Every day there are new technologies emerging; there are new frameworks available; there are new scenarios and devices to build for, so it becomes difficult as product owners, as developers, as technologists, to work out where to focus our attention. As we discussed in a recent article on App – Fomo before you jump into looking at technology it’s important to decide whether an app is even something you want to build. The true value of PWAs is that they are starting to bridge the cap between what the web can do today and the benefits offered by applications delivered by a store (eg place on the home screen, offline, push notifications). This in turn will ease make it easier to determine whether you truly need an app, or whether a modern responsive website (aka a PWA) will suffice.

          Slack, Teams and the Failings of the Universal Windows Platform (UWP)

          This is going to start of as a bit of a rant…. because it is – I’ve been building desktop and mobile applications using .NET since the first version of the .NET framework shipped many moons ago. In that time we’ve seen the rise and fall of various frameworks, patterns and technologies, all of which were supposed to make our lives as developers, designers and hopefully users better. Whilst the web seems to be this slowly devolving of JavaScript rot, you’d have thought that the .NET Framework after so many years would be everything that a developer needs in order to build amazing apps. Unfortunately, no, some idiot decided it would be great to run all that web-junk inside a native application.

          This brings me to the heart of my rant: Depending on our customers and suppliers, we toggle between Microsoft Teams, Slack, Skype, Skype for Business (now mostly deprecated in favour of Teams), HipChat, Hangouts and even Messenger. Whilst we all love to complain about how bad Skype is, the reality is that newer tools such as Teams and Slack are even worse. Both Slack and Teams are built using Electron and as far as desktop applications go, they are both as nasty as each other. They’re both slow; the user interface on both is painful and in no way takes advantage of the fact that I’m running on Windows. The operative word being Windows <<<—it has an S. I have to switch between multiple Slack channels and multiple Teams on a daily basis – they’re all in the same window; switching between them is slow (10-20secs); and it’s hard to keep track of conversations because notifications either don’t work, or are buried behind a single dot (not even a count as to how many unread messages).

          So why is it that things are so bad….. well it’s because the other options are no better. Take for instance the Universal Windows Platform – which is now only really Universal to desktop and Xbox because realistically they’re the only targets that you’ll consider (save some end cases for IoT and Hub). What a missed opportunity for Microsoft – they could have nuked the failed Xamarin Forms experiment in favour of extending UWP to really be the Universal Application Platform (UAP – oh wait, that’s the internal target framework for UWP already!!!); instead they’re sinking continued development effort into Xamarin Forms in the hope that it’ll one day be a viable alternative to Electron, Flutter, React Native….

          Talking of Xamarin Forms, is this such a bad platform? Well no, I actually quite like Xamarin Forms and I’ve personally invested a lot of time recently trying to help MvvmCross get to a stable v6 so that it can better support Xamarin Forms development. However, I would say that if you’re building for Xamarin Forms and you’re not using a third party Mvvm framework, you really need to – Microsoft’s continual assertion that Xamarin Forms has everything you need is just plain misleading and just leads to poorly architected applications.

          So, what is bad about Xamarin Forms? Well it’s hamstrung between at least three platforms (iOS, Android, Windows… Tizen, WPF….) in that they made a decision to rely on the native controls for each platform. React Native has a similar issue, since they decided on a similar approach. Flutter on the other hand has platform independent rendering and for that it’s getting a lot of attention. The design guidance from years ago that you should build for the platform UI is just plain wrong – you’ll end up with an application that just looks bad (lipstick on a pig!). You need to build applications that work for your brand – don’t design it multiple times, build it to suit your brand and your needs. You may decide to adopt some platform UX but the reality is that you want a button in your app to look the same on all platforms.

          Anyhow, enough of a rant about the failings of desktop apps…. until next time, enjoy losing hours of your day to responding to messages on Teams, Slack etc

          PWA Follow Up

          It’s clear that talking about Progressive Web Applications (PWAs) is all the rage. I noticed today that fellow Microsoft MVP, Adam Pedley who runs the Xamarin Help website and blog, posted about where PWAs and Xamarin.Forms fit. Whilst I’m not sure I agree with his opening statement about PWAs being started by Google (there is a long legacy of different browsers providing pseudo-offline features which pre-date the term PWA, so the concept itself isn’t new), I will definitely agree that it has been Google that has been championing the cause, with Microsoft adding some behind the curtain support (eg PWABuilder.com). One of the most interesting points that’s worth highlighting is the disconnect between the device features/capabilities that the web and client applications (native, Xamarin or Xamarin Forms) can take advantage of. Whilst the difference is being progressively eroded, there are still plenty of areas where a client application is the way to go. Shout out to https://whatwebcando.today/

          image

          What’s a Progressive Web Applications (PWA) and Why does my website want to be one?

          My last couple of posts (App or not to App and Cross-platform applications – PhoneGap/Cordova, Xamarin, PWAs and now Flutter) have been discussing different aspects of build applications. In particular in my previous post I discussed deployment models as being one dimension of applications. In this post I’m going to focus a bit more on the one of the hottest topics going around at the moment, Progressive Web Applications, or just PWA for short. If you’re new to this topic, I’d suggest a quick detour across to the Google developer site where they have an entire section dedicated to PWAs, and it’s a great starting point to understand the importance of PWAs and the experience that a good PWA should deliver.

          Side note: I had to laugh when I first went to the PWA page on the Google developer site as it talks about “A new way to deliver amazing user experiences on the web”. This is really what happens when you let the marketing get out in front of technology. Unfortunately I’ve see this type of propaganda so many times (Flash, Silverlight, HTML5) that it actually makes me a bit nervous as I start to think about another learning curve.

          image

          One of the quickest ways to get past the marketing fluff is to click the PWA Checklist button in the top right corner of the PWA page. Here’s a list of some of the other useful links on the Google developer site in relation to PWAs:

          - PWA Checklist

          - Lighthouse

          - PWA Summit videos (a bit dated but still a good place for building familiarity)

          Now that I’ve assigned you a bit of reading, let’s talk about what all the fuss is about. After scanning through the PWA checklist it becomes very evident that there are a couple of key topics: security, offline, seo and notifications. Let’s break these down, with specific attention to why they’re all important aspects of a great application (not just a PWA).

          Security

          Whilst not the first topic that comes up in regards to PWAs in the checklist it’s very evident that security first is still a key mantra when building the next generation of applications, which is made clear by the first item in the checklist which indicates that all content should be delivered across HTTPS.

          In the context of application development there has been an increase flow towards the use of HTTPS (for example the release notes for iOS9 by Apple indicated that all new apps should use HTTPS). Without HTTPS it’s just too easy for any third party to intercept and read/modify the traffic to and from the application.

          Offline

          This is a biggie when it comes to PWAs and in fact you could argue that this is probably the most significant departure from traditional web development. The introduction of service workers that can intercept requests, cache and dynamical change request behaviour opens the world to building intelligent offline-enabled applications. However, from an offline-ready application development perspective the current thinking in this space seems relatively immature, with most of the priority being placed on caching the components that make up the application (ie the HTML, CSS, JS that make up the application), rather than offline data and synchronisation scenarios.

          SEO

          Optimising your application for search has been one of those things that every developer says they’re going to do but rarely do they do it, and seldom is it done well. In terms of application development, one of the challenges faced by developers is how to define a set of deep links that will resolve both on the web and in the app. In structuring an application, it should be possible to provide an external link to any part of the applications, and in an ideal world the the link can be shared via any method, whether it be a link on social media, or via private correspondence such as chat or email. The upshot is that by structuring an application this way, you’re already half way there to making it indexable – you just need to make sure that the web application can be statically crawled so that relevant sections will appear in search results.

          Notifications

          Another aspect that tends to differentiate a good application is one where the user doesn’t have to keep on opening the application in order to see whether anything important has happened. All the native platforms, Windows, iOS and Android, have a rich push notification system that allow for interactivity and rich media in some cases. However, there is a disconnect as applications have to support multiple vendors that all support a slightly different push notification format. Notifications are important for a quality application as they help to keep the user informed about the things they care about most. The “Glance and Go” marketing campaign by Microsoft a number of years back for Windows Phone, whilst ultimately a failure (bye bye Windows Phone, we’ll miss you) it rang true in that notifications and badges are an extremely effective way of keeping users abreast of background activity within applications (either locally on the device, or remotely)

          Hopefully from this breakdown you can see that PWAs, whilst one of the hottest topics today, is far from “a new way to deliver amazing user experiences,” since application developers have been doing this since before the release of the iPhone. I guess the big distinction with PWAs is the “on the web”…. as in “please developers, stop building web sites with a crappy user experience, and start building rich applications that delight the user”. Perhaps some day we’ll break the dependency on the request-response model that has for so long governed the design of web sites.

          App or not to App

          Following my last post there were a couple of interesting tweets that made me revisit (again) the discussion of whether building an app is the right thing to do. For example, @GeoffreyHuntley said:

          Decision time:
          - #0 Don't make an app unless you absolutely have to.
          - #1 React + React Native (insane productivity)
          - #2 Xamarin (stagnating tbh)
          - #3 Flutter (innovator - watch this space)

          To be blunt, options 1-3 are all semi-painful – I’m not going to go into detail as to why, as that’s not the point of this post but needless to say that each one has their pros and cons, and none are what you’d consider an ideal development experience. Option 0 sounds like a great option and with the rapid development of Progressive Web Applications (with service workers being included by both React and Angular) it really does seem that not having to build an app is the way to go.

          Ok, but in that case, when would we build an application? Before we answer this, I think it’s worth revising what the notion of an “application” or “app” actually means. If you do a search for “App” on Wikipedia you get a number of responses:

          • Mobile app, software designed to run on smartphones and other mobile devices
          • Application software that causes a computer to perform tasks for computer users
          • Web application or web app, software designed to run inside a web browser

          (And particular note that the term “website” is not included here as according to Wikipedia a website is “a collection of related web pages” – personal opinion: if you still building for the web using the traditional post-back model (yes, looking at you ASP.NET) you’re building a website, not an app).

          Let’s ignore for the moment the distinction between mobile, web or any other qualifier about the type of an application or the target platform and instead, let’s focus on what an application is. According to Wikipedia an Application is software that causes a computer to perform tasks for a user. This is a pretty wide definition and essentially encompasses most software, whether it be a command line application, browser or window based application. However, if you were to ask most people what they thought an “App” was today, they’d probably give an answer that relates to installing an application from the Apple, Google or Windows Store – it seems like the notion of an App is in somehow attached to the distribution model.

          If we look further into this, there are a variety of distribution models:

          - An application that you simply download from the Internet and just run (it might download as a Zip file but the important distinction here is that there’s no installation process and no Store managing the application). This is by far the simplest distribution model. However, these days few applications are distributed this way as most operating systems distrust downloaded files from the Internet and will refuse to run them without them being “unblocked” first.

          - An application you download from the Internet and then install. For Windows and MacOS historically this was the most common way for applications to be distributed. The operating system didn’t have a built in distribution mechanism, such as a Store, but they did support a model for applications to be installed and uninstalled. The danger of this model, is that, similar to just downloading and running an application, an application that is installed could have wide-reaching access to the host operating system. Over time this model has be adapted and additional security (for example User Account Control on Windows) limited what an installed application could do

          - An application you install from a Store. Whilst this model did exist prior to the iPhone, it wasn’t really until the App Store launched that the notion of a single curated Store became mainstream. Now, most platforms have a Store where you can browse, search and install apps to suit your every need. Depending on the platform, the process for submitting, certifying and publishing applications varies, with different levels of quality and policy controls imposed in order to try to maintain a high quality bar for apps. The Store also takes on responsibility for distributing updates to application as they become available, as well as providing a mechanism for developers to charge for their applications.

          - An application you load in the browser. Most people don’t really consider websites that they navigate to in the browser as applications. However, websites are becoming highly functional and most no longer require a full post-back in order to load more content, improving the usability. In fact, browsers have tried to prompt web sites as pseudo-apps by allowing users to add a web site to a list of applications (for example the “Apps” icon that appears within Chrome under the address bar).

          image

          - An application you install via the browser. In contrast to adding a website to a list of applications within the browser, installing a website via the browser allows the website to take advantage of a lot of the benefits of applications installed via a Store. They can appear as an icon on the home screen (or list of applications installed on the device); they run without the browser chrome; they can receive push notifications and much more.

          So the question is whether the distribution model is what defines what an “App” is?

          When we embark on building an application do we need to lock ourselves into one of these distribution models, or can we pick multiple, or all of these distribution models. Or, is the distribution model different for each platform? To answer this we really need to consider the pros and cons of each mechanism and the corresponding audience reach it gives us, and whether it makes sense to choose a particular distribution model.

          Cross-platform applications – PhoneGap/Cordova, Xamarin, PWAs and now Flutter

          At Built to Roam we build applications that target a wide array of different platforms, using a wide variety of technologies depending on the project requirements. One of the most challenging things faced by organisation looking to build any form of software is often not what should I build, it’s often what technology should I use to build it. Unfortunately this is also where the most cycles are wasted and the poorest decisions are made.

          Nirvana would be building the software once, and for it to be available on every platform and device type, able to be instantly updatable and have a rich and engaging user interface (and I’m sure there’s more things that needed to be bolted onto this list of “ideals”). However, the reality is that there are different device types and sizes; there are different technologies with differing capabilities; and different developer and deployment workflows. Rather than being able to make an absolute decision on the best strategy, companies are limited by their own field of influence. Too often this includes Gartner reports, media hype and both internal and contractors with whom the decision makers have a relationship with.

          In addition to the number of options that are available, the optimum strategy also evolves over time. For example, five years ago in Australia it made sense for organisations to start their investment in mobile apps with a fairly basic iPhone application. Today the market expectation is that a mobile strategy encompasses at least Android and iOS, phone and tablet, and with a comprehensive set of features. In fact some applications, don’t even have a web presence, finding that their mobile apps were sufficient for their business model.

          So the question is really whether it is possible to define the optimum strategy for a business and is it possible to future proof it?

          To investigate this a bit further, let’s take a look at the progression of native application development. What’s quite interesting is that businesses have woken up to the fact that maintaining multiple applications written in the preferred technology for each platform is not sustainable. This has led to the emergency of a host of cross platform tools that generate native applications. There are tools such as Xamarin/Xamarin Forms which compile C# so that it can be run on the target platform; There has also been an explosion in Javascript based solutions, such as React Native where it generates the native components for each platform based on HTML mark-up (+CSS, JavaScript etc); More recently again there is Flutter, which aims to provide a user experience that has been drawn from the ground up to be platform agnostic. How do you make a decision between these technologies?

          More importantly is – are you making the decision about the right thing? It would seem that making a decision about which native application toolset to use would be right but actually the web and some of the hybrid solutions solve so many challenges that native application developers face, it would be foolish to ignore them. Take for example the recent hype around Progressive Web Applications. There are some who believe this is just another round of hype about the newest buzzword to arrive on the scene but in actual fact whilst the name is new, the concept is not. Back even in the days of Windows Vista, there were desktop gadgets that essentially allowed parts of the web to run in a container in an offline capacity. PWAs are just the latest name to be given to this concept.

          Where PWAs are set to make a difference is that they are being widely backed (eg Google: https://developers.google.com/web/progressive-web-apps/ and Microsoft: https://pwabuilder.com) and they also arrive at a point in time where devices have browsers and rendering engines that are capable of delivering a high-performance web experience whether in-browser, or in a hosted web application.

          Do you think the market is ready for PWAs? or are native applications going to rule for the foreseeable future?

          New BuildIt Release for NetStandard 2.0 (General, States and Forms)

          A new release of the following libraries is available via NuGet (v1.1.0.134):

          - BuildIt.General

          - BuildIt.States

          - BuildIt.Forms

          Whilst not much has changed in terms of features, behind the scenes there was quite a significant change as we adjusted the solution/project structure, and thus the nuget package structure. We took advantage of the ability to multi-target which meant we no longer have to have separate projects/libraries in order to support platform specific features. BuildIt.General, which used to have a UWP specific library, is now a single libary. Same goes for BuildIt.States. BuildIt.Forms has two libraries, down from the 5 that it used to have.

          Additionally we also added direct support for netstandard 2.0. As part of the build process, each library is compiled for netstandard 1.0, netstandard 2.0 and then any platforms that have additional features.

          In this release we’ve released multiple packages with the same version number, even though there is an interdependency between them (Forms –> States –> General).

          Please reach out and let me know if you see any issues in this release with any of these libraries. We’ll be working to release updates to the other BuildIt libraries over the coming weeks.

          Building Applications for Platform X

          As we get started with a new year it’s time to pause and think about how the app development ecosystem has evolved, what technologies continue or are emerging, and look at the decision matrix that will define what technology your next application is developed in. I’m going to treat this post as a bit of an intro to some of the technologies that I think are worth further investigation.

          I think the easiest way to do this is to walk the spectrum from web apps through to native platform apps:

          Web Apps

          When we talk about web apps, there is a natural assumption that these will be responsive web sites that will work across a wide range of devices and browsers. However, they can be divided further into what I would consider traditional web sites and single page applications. Whilst this division can be blurred, for example when you host an Angular application within a .NET core application, the point is that there is a difference in the mindset of the developers building the web app.

          Of course, this section includes the obvious ASP.NET Core, React and Angular. Whilst ASP.NET is still a valid choice, I specifically left it out of the list as I think most new projects will favour ASP.NET Core unless there is an impediment that requires full ASP.NET.

          Progressive Web Applications allow web developers to extend their applications to leverage more device capabilities. This is a particularly hot area of development for most platforms as this is seen as one of the best long term solution for minimising mobile development fatigue.

          Hybrid

          Next in the progression are hybrid applications which combine web technologies with a platform specific deployment package – this sounds a bit cryptic but that’s because there are a couple of different models for this.

          Firstly there’s the Cordova/PhoneGap model where the application is defined using html, css, javascript, and wrapped in a native platform deployment package. The deployment step is required in order for most stores to accept applications. The important thing here is that the layout and logic for the application is packaged with the application and that the platform web rendering engine is used to display the application.

          The second model is much more interesting and is one that’s being used by React Native and Native Script where the logic and layout is defined in javascript, css and a form of HTML. The HTML actually defines native elements that will be rendered in the correct location.

          Cross Platform

          Before we get to native platform tools and technologies, we’ll stop in on a long time friend, Xamarin. As with the previous sections there are again two options with Xamarin: traditional Xamarin, and Xamarin Forms. With the traditional Xamarin approach the developer is much closer to the metal and has a higher degree of control. However, the Xamarin Forms option allows for user interfaces to be rapidly developed once, and then feedback/issues are resolved on a platform by platform basis.

          Native Platform

          Lastly, we have the Native platform options for developers:

          Android

          Java, C++ with Eclipse, Android Studio

          iOS

          Objective C, Switft, Interface Builder (now part of XCode)

          UWP

          C#, XAML, Visual Studio (or Visual Studio for Mac)

          As this is hopefully one in a sequence of posts on the topic of framework selection, I’d love some feedback on what technology you think will be important to you and those you work with – comments are off but hit me up on twitter @thenickrandolph if you have thoughts on this.

          Making MvvmCross with Xamarin Forms Friction Free

          My last two posts (part 1 and part 2) outlined all the steps necessary to get a new Xamarin Forms with MvvmCross project setup. What I thought was going to be a simple post ended up being much longer due to all the unnecessary steps to setup both Xamarin Forms and MvvmCross. I’ve recently been contributing a little to MvvmCross and one of my concerns with it is that there are just way to many things that you need to get right in order to get it to work nicely with Xamarin Forms. If you don’t follow one of the introductory posts, such as the one provided by Martjin van Dijk, you’ll probably start hacking around with the numerous extension points in order to get it to work. I spent time over the last day seeing if I could reduce this initial friction to getting started.

          When you adopt a framework, or any library for that matter, you do so to reduce the need to reinvent the wheel – there’s no point in recreating, or creating something new, if there are existing solutions available. However, I’m of the opinion that you should be able to determine how much the framework influences the way that your code is structured. You should only have to modify your code if the framework offers a clear advantage. If we do a quick review of some of the changes required to take advantage of MvvmCross in our Xamarin Forms project you’ll see that quite a few of these are artificial requirements, mandated by the current MvvmCross implementation, rather than for any specific need. Here are just a couple:

          • App needs to inherit from MvxFormsApplication – this doesn’t add anything other than a couple of events, so unless you want to use those events, this is unnecessary
          • All pages need to inherit from the Mvx equivalent (eg MvxContentPage instead of ContentPage) – the Mvx equivalent expose a ViewModel property which can be useful but is not required in order to take advantages of data binding to the corresponding ViewModel since all Forms elements have a BindingContext that’s used for this purpose. The actual requirement here is for views/pages to implement IMvxView but unless you need the ViewModel property this shouldn’t be a requirement.
          • You need to create a class that inherits from MvxApplication which can do things like register services but most importantly defines what the starting ViewModel is going to be. This is kind of unnecessary if the only thing that it’s doing is defining the starting ViewModel, although I do understand the desire to have the starting ViewModel defined somewhere that is independent of the head projects.
          • All ViewModels need to inherit from MvxViewModel or implement IMvxViewModel – again this is somewhat unnecessary since ViewModels should just be a regular class. Now I do agree that in most cases your ViewModel is likely to implement INotifyPropertyChanged, so this additional requirements isn’t a massive addition but needless to say it shouldn’t be a requirement.

          Ok, so after a bit of experimenting without modifying MvvmCross or MvvmCross.Forms (ie I’m just using the NuGet packages) what I came up with is BuildIt.MvvmCross.Forms (currently in prerelease!) which is a NuGet package which adds a couple of helper classes to get you going just that bit quicker. Here are the steps to get started using BuildIt.MvvmCross.Forms:

          Start by following the steps outlined in part 1 – this will give you a Xamarin Forms project that’s completely up to date. I’ll call this project LowFriction

          Next, follow the early steps in part 2 to add an additional project for your ViewModels, LowFriction.Core, and subsequently add references to MvvmCross (to all projects) and MvvmCross.Forms (to all projects except the Core project).

          Add a reference to the BuildIt.MvvmCross.Forms NuGet package to all projects except the Core project. A primary requirement here is that the Core project should not have a reference to the view technology, which in this case is Xamarin Forms – if you find yourself adding a reference (directly or otherwise) to Xamarin Forms to your Core project, you’ve done something wrong and you should rethink the decisions that led you to that point.

          You still need to change App.xaml to inherit from MvxFormsApplication – I couldn’t find a work around this requirements

          Your pages do not need to change to implement iMvxView – MainPage inherits from ContentPage

          In your Core project you will need to create ViewModels that map to your pages, and they need to implement iMvxViewModel – again I couldn’t find a work around for this requirement. MainViewModel inherits from MvxViewModel.

          In your Core project you do not  need to create a class that inherits from MvxApplication – we’ll come to this later but essentially BuildIt.MvvmCross.Forms has class called TypedMvxApplication whose type parameter is the starting ViewModel. If you do want to extend the MvxApplication you can still create your own application but I would recommend using TypedMvxApplication as a starting point

          UWP

          In App.xaml.cs replace

          Xamarin.Forms.Forms.Init(e);

          with

          var setup = new SetupFromViewModel<MainViewModel, LowFriction.App>(rootFrame, e);
          setup.Initialize();

          You can see here that the SetupFromViewModel class accepts the starting ViewModel as a parameter. If you’d prefer to define the starting ViewModel in the Core project I recommend defining a class that inherits from TypedMvxApplication, specify the starting ViewModel as the type parameter, and then use the SetupFromApplication class in App.xaml.cs.

          Change MainPage to inherit from BuildIt.MvvmCross.Forms.UWP.MvxFormsWindowsPage (I also updated the layout of MainPage to show some data coming from databinding from the ViewModel, similar to what I did in my previous post)

          Change the MainPage constructor to

          public MainPage()
          {
               this.InitializeComponent();

              MvxLoadApplication();
          }

          Android

          Change MainActivity to inherit from CustomMvxFormsAppCompatActivity<SetupFromViewModel<MainViewModel, LowFrictionApp>, MainViewModel>

          Comment out the Xamarin Forms init code:

          //global::Xamarin.Forms.Forms.Init(this, bundle);
          //LoadApplication(new App());

          iOS

          Change AppDelegate to inherit from CustomMvxFormsApplicationDelegate

          Change FinishedLaunching

          public override bool FinishedLaunching(UIApplication app, NSDictionary options)
          {
               Window = new UIWindow(UIScreen.MainScreen.Bounds);

              var setup = new SetupFromViewModel<MainViewModel, App>(this, Window);
               setup.Initialize();

              MvxLoadApplication();

              Window.MakeKeyAndVisible();

              //global::Xamarin.Forms.Forms.Init();
               //LoadApplication(new App());

              return base.FinishedLaunching(app, options);
          }

          And we’re done! Build and run on each platform and you should be good to go.

          As you can see there are significantly fewer steps involved in getting started, and few additional classes to be created. I do note that there is still room for improvement and I feel that as frameworks go MvvmCross has been developed with extensibility in mind – which is why I was able to streamline the getting started experience so much.

          Getting Started: MvvmCross with Xamarin Forms (Part 2)

          In my previous post I covered the first part of this post on Getting Started with MvvmCross and Xamarin Forms where I covered the initial steps in getting a new Xamarin Forms project started. In this post I’m going to continue on and show how you can configure a Xamarin Forms solution to make use of MvvmCross.

          Before I get started with MvvmCross I’m going to add a new project which will contain all my ViewModels. Whilst not entirely necessary, particularly with Xamarin Forms where the views/pages are in a .NET Standard library, it’s good practice to completely separate your ViewModels away from the views/pages to avoid any accidental interdependencies forming. I’ll add a new project based on the .NET Standard class library template.

          image_thumb11[1]

          For this library I’m going to adjust the .NET Standard version back to 1.0 – I prefer to start with a low .NET Standard version and increase it only when I need to take advantage of features in the higher versions. This ensures that the library can be referenced by the widest set of targets platforms.

          image_thumb11

          I’ll add a reference to the new project to each of the other projects in the solution.

          image_thumb31

          The next step is to add a reference to the MvvmCross NuGet package. Currently MvvmCross is still distributed as a set of Portable Class Libraries and if we attempt to add the NuGet package to either our MvvmcrossGettingStarted or MvvmcrossGettingStarted.Core projects, we’ll get an error as they’re both .NET Standard library. What’s annoying about this is that the MvvmCross PCLs are fully compatible with .NET Standard, meaning that it should be possible to add a reference to them. Unfortunately Visual Studio isn’t clever enough to be able to resolve this, and as such we need to adjust the csproj files for both projects before attempting to add a reference to MvvmCross.

          Add the following line into the first PropertyGroup of the csproj files for both MvvmcrossGettingStarted or MvvmcrossGettingStarted.Core projects. One saving grace is that it’s now easy in Visual Studio to edit a csproj by right-clicking on the project and selecting “Edit <project name>.csproj”.

          <PackageTargetFallback>$(PackageTargetFallback);portable-net45+win8+wpa81</PackageTargetFallback>

          Eg.

          image_thumb23

          Next we can go ahead and add a reference to MvvmCross to all our projects. Right-click on the solution node in Solution Explorer and select Manage NuGet Packages for Solution, and then search for mvvmcross. Select the most recent stable version of MvvmCross (this image is a little old as the version is at 5.6.3 at time of writing this)

          image_thumb9

          In addition to the main MvvmCross package, we also want to add in the Xamarin Forms support library, MvvmCross.Forms. Note that we do not add this to the MvvmcrossGettingStarted.Core project – this is the separation of concerns we setup at the beginning of this post to ensure there is no dependencies on the viewing technology within our ViewModels.

          image_thumb21

          Now that we have added the references to MvvmCross there are a bunch of small changes we need to apply to our application in order to get it all up and running. We’ll start in the MvvmcrossGettingStarted.Core project where we need to create two classes.

          The first class we’ll create inherits from MvxApplication and is used to setup the application within the ViewModel world. MvvmCross has an opinionated navigation model whereby navigation is defined at a ViewModel level, and simply implemented at a View level. As such the MvxApplication class, in this case GettingStartedApplication, defines the first ViewModel for the application.

          public class GettingStartedApplication : MvxApplication
          {
               public override void Initialize()
               {
                   RegisterNavigationServiceAppStart<MainViewModel>();
               }
          }

          The second class is the ViewModel that matches the first view or page of the application. MainPage was created back when we created the Xamarin Forms application, so we’ll create a class called MainViewModel. Whilst you can override the default view to viewmodel mapping in MvvmCross, it’s preconfigured to align views and viewmodels based on a naming convention. I typically stick with XXXViewModel and XXXPage but XXXView is also supported out of the box.

          In this case MainViewModel exposes a simple property that we’ll data bind to later to show that the Page and ViewModel have been glued together correctly.

          public class MainViewModel: MvxViewModel
          {
               public string WelcomeText => "Welcome to my data bound Xamarin Forms + MvvmCross application!";
          }

          Now we’ll switch over to the MvvmcrossGettingStarted project and make some changes to both the App and MainPage classes.

          In the App.xaml, we need to change the root element to reference MvxFormsApplication

          <?xml version="1.0" encoding="utf-8" ?>
          <mvx:MvxFormsApplication xmlns="
          http://xamarin.com/schemas/2014/forms"
                               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                               xmlns:mvx="clr-namespace:MvvmCross.Forms.Platform;assembly=MvvmCross.Forms"
                              
          x:Class="MvvmcrossGettingStarted.App">
               <Application.Resources>
               </Application.Resources>
          </mvx:MvxFormsApplication>

          And in App.xaml.cs, remove the inheritance – the Microsoft templates insist on including the inheritance in both the xaml and xaml.cs files which is quite unnecessary and should be removed.

          public partial class App
          {
               public App()
               {
                   InitializeComponent();
               }
          }

          We need to make a similar change to MainPage.xaml, changing the root element to MvxContentPage. We’ll also change the Label to use data binding to return the WelcomeText property from the MainViewModel.

          <?xml version="1.0" encoding="utf-8" ?>
          <mvx:MvxContentPage xmlns="
          http://xamarin.com/schemas/2014/forms"
                               xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                               xmlns:local="clr-namespace:MvvmcrossGettingStarted"
                               xmlns:mvx="clr-namespace:MvvmCross.Forms.Views;assembly=MvvmCross.Forms"
                              
          x:Class="MvvmcrossGettingStarted.MainPage">
               <Label Text="{Binding WelcomeText}"
                      VerticalOptions="Center"
                      HorizontalOptions="Center" />
          </mvx:MvxContentPage>

          Again, remove the inheritance specified in MainPage.xaml.cs

          public partial class MainPage
          {
               public MainPage()
               {
                   InitializeComponent();
               }
          }

          The next step involves adding a Setup class to each of the head projects, and then creating an instance of the Setup class to invoke MvvmCross when the application starts up.

          UWP

          The UWP Setup inherits from MvxFormsWindowsSetup and unlike the Android and iOS Setup classes, the UWP Setup needs to override the default log behaviour by setting the log provider type to None and then creating an instance of the EmptyVoidLogProvider  (the implementation of this is coming up soon) – this should be fixed in a future MvvmCross version.

          public class Setup : MvxFormsWindowsSetup
          {
               public Setup(Frame rootFrame, LaunchActivatedEventArgs e) : base(rootFrame, e)
               {
               }

              protected override MvxLogProviderType GetDefaultLogProviderType() => MvxLogProviderType.None;

              protected override IMvxLogProvider CreateLogProvider() => new EmptyVoidLogProvider();

              protected override IEnumerable<Assembly> GetViewAssemblies()
               {
                   return new List<Assembly>(base.GetViewAssemblies().Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly }));
               }

              protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

              protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
          }

          Now in App.xaml.cs we need to replace

          Xamarin.Forms.Forms.Init(e);

          with

          var setup = new Setup(rootFrame, e);
          setup.Initialize();

          And in Main.xaml.cs replace

          LoadApplication(new MvvmcrossGettingStarted.App());

          with

          var start = Mvx.Resolve<IMvxAppStart>();
          start.Start();

          var presenter = Mvx.Resolve<IMvxFormsViewPresenter>() as MvxFormsUwpViewPresenter;
          LoadApplication(presenter.FormsApplication);

          Finally, we need to add the EmptyVoidLogProvider

          public class EmptyVoidLogProvider : IMvxLogProvider
          {
               private readonly EmptyVoidLog voidLog;

              public EmptyVoidLogProvider()
               {
                   voidLog = new EmptyVoidLog();
               }

              public IMvxLog GetLogFor<T>()
               {
                   return voidLog;
               }

              public IMvxLog GetLogFor(string name)
               {
                   return voidLog;
               }

              public IDisposable OpenNestedContext(string message)
               {
                   throw new NotImplementedException();
               }

              public IDisposable OpenMappedContext(string key, string value)
               {
                   throw new NotImplementedException();
               }

              public class EmptyVoidLog : IMvxLog
               {
                   public bool Log(MvxLogLevel logLevel, Func<string> messageFunc, Exception exception = null, params object[] formatParameters)
                   {
                       return true;
                   }
               }
          }

          Now when we build and run the UWP project we can see that the MainPage is shown and is data bound to the MainViewModel.

          image

          iOS

          The iOS Setup is the simplest out of the three platforms.

          public class Setup : MvxFormsIosSetup
          {
               public Setup(IMvxApplicationDelegate applicationDelegate, UIWindow window)
                   : base(applicationDelegate, window)
               {
               }

              protected override IEnumerable<Assembly> GetViewAssemblies()
               {
                   return new List<Assembly>(base.GetViewAssemblies().Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly }));
               }

              protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

              protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
          }

          In AppDelegate we need to change the inheritance from  global::Xamarin.Forms.Platform.iOS.FormsApplicationDelegate to MvxFormsApplicationDelegate and change the FinishedLaunching method as follows:

          public override bool FinishedLaunching(UIApplication app, NSDictionary options)
          {
               Window = new UIWindow(UIScreen.MainScreen.Bounds);

              var setup = new Setup(this, Window);
               setup.Initialize();

              var startup = Mvx.Resolve<IMvxAppStart>();
               startup.Start();

              LoadApplication(setup.FormsApplication);

              Window.MakeKeyAndVisible();

              return base.FinishedLaunching(app, options);
          }

          Now we’re good to build and run the iOS project

          image

          Android

          Lastly, add Setup to the Android project. Note this is slightly different from the iOS and UWP projects in that the GetViewAssemblies method excludes the assembly for the Android head project. This is to avoid the MainActivity being added as a view, that based on our naming convention would match with MainViewModel giving a duplicate when attempting to resolve the View that should be rendered.

          public class Setup : MvxFormsAndroidSetup
          {
               public Setup(Context applicationContext) : base(applicationContext)
               {
               }

              protected override IEnumerable<Assembly> GetViewAssemblies()
               {
                   return new List<Assembly>(base.GetViewAssemblies()
                       .Union(new[] { typeof(MvvmcrossGettingStarted.App).GetTypeInfo().Assembly })
                       .Except(new[] {this.GetType().Assembly})
                       );
               }

              protected override MvxFormsApplication CreateFormsApplication() => new MvvmcrossGettingStarted.App();

              protected override IMvxApplication CreateApp() => new Core.GettingStartedApplication();
          }

          The MainActivity needs to be updated to change its inheritance from global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity to MvxFormsAppCompatActivity<MainViewModel>. And the OnCreate needs to be updated to

          [Activity(Label = "MvvmcrossGettingStarted", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
          public class MainActivity : MvxFormsAppCompatActivity<MainViewModel>
          //global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
          {
               protected override void OnCreate(Bundle bundle)
               {
                   TabLayoutResource = Resource.Layout.Tabbar;
                   ToolbarResource = Resource.Layout.Toolbar;

                  base.OnCreate(bundle);

                  var startup = Mvx.Resolve<IMvxAppStart>();
                   startup.Start();
                   InitializeForms(bundle);

               }
          }

          Finally the last platform, Android, is good to build and run. Note however that Android has a tendency to be a pain and that after setting everything up correctly you may still run into issues building, deploying and running. Before you waste hours looking at your code to see what you’ve done wrong, make the assumption that the tools are crap – delete both bin and obj folders from the Android head project, and uninstall the application from the device/emulator (assuming it has already been installed). Try building and running again – if this still fails, then you may indeed have something wrong with your code!

          image

          Getting Started: MvvmCross with Xamarin Forms

          Over the past 6-12 months we’ve seen dramatic changes in Xamarin Forms and the support within Visual Studio. The most recent update, which I covered in my previous post, included a number of new features for cross platform developers. However, despite these updates, getting started with cross platform development is still quite complex. In this post I wanted to take the opportunity to reiterate how to start a new Xamarin Forms project. From there I’ll cover adding in MvvmCross and discuss the importance of having a framework that will make development that much easier (for the record MvvmCross isn’t the only option, there are plenty of great alternatives such as Prism and FreshMvvm).

          Part 1: Getting Started with Xamarin Forms

          Before getting started, make sure you’ve run the Visual Studio Installer and have upgraded to the latest stable release of Visual Studio. The team at Microsoft have been putting a lot of focus on stability and performance, so upgrading to the latest version does help (still not perfect but a marked improvement over this time last year!). Upgrading Visual Studio continually can be a bit of a pain, especially since Microsoft haven’t quite worked out how to automatically download updates in the background for VS – meaning that you have to stop whatever you’re doing whilst the updates download and then install. Recommendation is to run the installer periodically at the end of your day, or when you’re heading to a long meeting; hopefully the installation is complete by the time you return.

          Now that you’re all up to date, let’s create a new solution by selecting the Cross-Platform App (Xamarin Forms) template from the New Project dialog. Note that if you don’t see this template, you may have to adjust the workloads you selected in the VS Installer so that you have all the cross-platform development components selected.

          image

          After clicking OK you should be presented with a second dialog that allows you to specify parameters for how your cross platform project should be setup. As you can see from the image, I recommend always selecting all three platforms (even if you’re only planning on targeting one or two of them initially); In this case we’re going with Xamarin.Forms with a simple Blank App; The last option I’m particularly passionate about – do NOT select Shared Project – for the good of your project, the team and general good programming practice, please select the .NET Standard option for Code Sharing Strategy. At time of writing the .NET Standard option is only available in the preview build of Visual Studio; the stable build uses a Portable Class Library, which is still preferable over using a Shared Project.

          image

          This time clicking OK will create a new solution.

          Unexpected Error when Creating Solution

          Unfortunately, at time of writing this post there is also a bug in the current cross platform template that results in the following error:

          image

          If you see this error, a quick Google will yield the following bugzilla issue (https://bugzilla.xamarin.com/show_bug.cgi?id=60995) which describes the issue, along with how to fix it yourself – you just need to edit the Android csproj file and remove the " from around the TargetFrameworkVersion ie:

          replace:

          <TargetFrameworkVersion>"v8.0"</TargetFrameworkVersion>

          with
          <TargetFrameworkVersion>v8.0</TargetFrameworkVersion>

          After fixing up the csproj file you’ll need to add the existing projects into the solution file.

          Assuming you didn’t run into any issues creating the solution, or you were able to fix up the Android csproj file, you should be able to build and run each of the head projects:

          UWP

          image

          Note: When building the UWP project I was seeing a build warning stating “warning APPX0108: The certificate specified has expired.” which I thought was a bit odd since I had just created the project and normally the certificate that is used for debug builds is created alongside the new project. Double-clicking the package.appxmanifest and switching to the Packaging tab I see that the Publisher display name isn’t set correctly – I’m guessing at this point that the cross platform template contains an existing certificate, instead of creating one each time. You can easily fix this by changing the publisher display name, clicking Choose Certificate and then from the dropdown select “Create test certificate”.

          image

          Now when you build the project you won’t see this warning – I’m guessing this is also a bug in the preview version of the cross platform template.

          Android

          image

          For Android I’m using the Google Android Emulator that can now be installed using the Visual Studio Installer. This is significantly better than it used to be, and the images are much more recent than those for the Visual Studio Android Emulator which has been deprecated now.

          iOS

          image

          For iOS, as I’m working from a Windows laptop, I use the Remote Simulator which works really well and means I don’t need to continually VNC to my MacMini or have to deploy to a real device.

          Again there was an issue with the iOS template in that the MinimumOSVersion was set to “11.2” instead of just 11.2 in the Info.plist file.

          <key>MinimumOSVersion</key>
          <string>11.2</string>

          Correcting the MinimumOSVersion will allow your application to run on a device or emulator.


          Now that we’ve validated that all the platforms run, it’s time to make sure they’re setup correctly ready for us to add in Mvvmcross and to set the foundation of our application. Android and iOS should be setup correctly, although you may want to double-check to make sure Android is set to use the latest platform version (see Application tab of the Android project properties); UWP defaults to using the Fall Creators Update (FCU) as the minimum version, which is way to recent for applications wanting to target the widest set of customers. Our preferences is to set this back to the November Update

          image

          Note however, that this does preclude your application from using .NET Standard 2.0 libraries, as these are not compatible with UWP projects prior to the FCU. Unfortunately the .NET Standard library that holds the Xamarin Forms views for the solution is set to .NET Standard 2.0 by default. This is completely unnecessary, so it can be reduced back to 1.4 (or below, depending on your preferences)

          image

          Next, we want to make sure we’re using the latest NuGet packages – right-click on the solution node in Solution Explorer and select Manage NuGet Packages for Solution

          image

          After upgrading all the NuGet packages, double-check to make sure all platforms build and run. Now’s a great time to check your solution in to your repository of choice (Note: make sure you check in the pfx file that is part of the UWP solution. You’ll probably have to manually add this file to your repository as most repositories ignore pfx files by default).

          Update: Part 2 is now available.