XF vs PWA: Getting Started With XF

Setting Up Your Project

In my Xamarin Forms vs PWA experiment, I thought I would get started with Xamarin Forms first. The first thing we are going to do is create the project. For those that don’t know, you can find the Xamarin Forms project templates under cross-platform in the category tree on the left.

ProjectSetupXF1

Next you will have to select the type of project. I prefer to use the blank app template and the platforms depend on what I am doing. I find that even if I don’t need a UWP app, I select it anyways as I find it easiest for debugging. I am also a fan of using the standard library for the common code instead of the shared project: you are only compiling the shared project once instead of including it to be compiled for each of the clients. But both work so use whatever you prefer.

ProjectSetupXF2

Alright, so after we let it restore all of the necessary packages, we can get started. If you have read any of my other posts, you know that I am a big fan of the work that the team with Prism Library do, and back it up with a Patreon pledge (if you love Prism, you should consider it as well). So the next step will be to setup Prism with my app.

Adding Prism

The easiest thing to do here is obviously to use NUGET to add Prism to your project. You can search for Prism.Unity and that will bring in the packages that use Unity.Container as the dependency injection container.

PrismUnityPackage

I should note here that I am going to use the pre-release version of the packages. As such, I am going to go to the GitHub repository and download the packages and use them in my workspace. Go to the 7.1.0-Pre tag to download the latest that I used. Why would I download and include the projects manually? If you haven’t done this before, I would recommend trying it sometime with a library of your choice. If you are relying on a package of some kind, I think it is a good idea to have at least a base understanding of how things are working within the code that you are relying on. And if something isn’t working as expected, it is pretty easy to step right into the library code itself and see what is going on. This is the first time that I have used the 7.x version of Prism so I want to see what the changes are.

If you do download the source and add it to your project manually, you will have to include the projects in your solution. Once they are in the solution, remember to go the core project and each of the platform projects and add them as project references.

Bootstrapping Your App

If you have done any Xamarin Forms projects in the past, you know that there is an Application object that is used to start up your app. This object is contained in the core project common to all the platforms. We are going to change our Application object to derive from the PrismApplication object. If you are poking around, you will probably find a PrismApplicationBase object in the Prism.Forms assembly and a PrismApplication object in the Prism.Unity.Forms assembly. We want to use the one that is derived for the container of our choice: Unity.Container.

Head on over to your core project and open up the App.xaml file. You are going to need to update the root tag to be PrismApplication and do that you will need to add the appropriate namespace to the XAML namespace declarations. Your XAML would then look like the following:

    

Don’t forget the code behind.  In addition to change the base class, Prism imposes a pair of methods that you must define: RegisterTypes and OnInitialized. First, let’s fix up the class declaration and the constructor. For now, ignore the IPlatformInitializer, we will talk more about that in another post.

public partial class App : PrismApplication
{
    public App(IPlatformInitializer initializer = null)
        : base(initializer)
    {
    }

    /// ...
}

The RegisterTypes method is used to register all the navigation pages that the navigation service uses and all of the services that you want to consume in your app. An example might be the service that calls an external web api. Although we haven’t gotten to that point yet, this sample project will call a web api that gets data from the local transit authority. We will see that a bit later.

For now, all we want to do is to register our pages for navigation, of which we only have one.

protected override void RegisterTypes(IContainerRegistry containerRegistry)
{
    containerRegistry.RegisterForNavigation("main");
}

That was pretty easy. If we had a view model for our MainPage defined yet, we could also register it as part of the above call. And then whenever the navigation service created the page, it would also create the view model and inject it for us.

Next, we look at the OnInitialized function. This gets called after all of the initialization has happened and your app is ready to show the first page. For us it will be very simple, we just call the base class InitializeComponent method and then ask the navigation service to go the first page.

protected override void OnInitialized()
{
    InitializeComponent();
    NavigationService.NavigateAsync("main");
}

In the above, the NavigationService looks for the page type that you registered against the “main” key, creates it and pops it up on to the Xamarin Forms navigation stack. Just to make sure everyone grasps the coolness part of the navigation service, you perform your navigation using arbitrary strings, therefore your objects are not coupled together and it is dead easy to swap in new pages without affecting the rest of your code.

Excellent! This should get you going with a shell app that you can run on each of the platforms that you created for. Once caveat though: I sometimes find Visual Studio to be a bit finicky when you start changing the XAML base class in the app object. I usually find that some combination of cleaning the solution and restarting Visual Studio clears this up, so be aware of that. Since I specified a UWP project as well, I haven’t tried to open it up in Visual Studio for Mac to see if that is less fragile. Once Visual Studio wraps its mind around it though, you should be good to go.

Next thing we will look at is adding in our master/detail, hamburger menu and place holder pages for the different options on the menu.

Xamarin Forms vs PWA

I have been pretty interested in PWA’s lately. In case you don’t know, PWA is a progressive web app. The progressive part is about how the app reacts with more or less capability in the host browser. It also gives the web app some native capabilities such as notifications so that the app appears almost like a native app.

As a bit of a fun side project, I thought I would take a transit status app that I have in UWP and rewrite for Xamarin Forms across Android, iOS and UWP. Then I would rewrite it as a PWA. Fun!

I think this one will take a while to complete though. We shall see. Hopefully what comes out of this are some cool things I learn with each approach and some informative blog posts. On the Xamarin Forms side, I am going to use the latest release of Prism for Xamarin Forms. The Prism team has been doing some amazing work and have recently set themselves up on Patreon for funding.  I signed up for funding them, if you use their libraries, please consider doing the same.

On the PWA side, I will use Angular as a framework. I know some people don’t like any frameworks (too much weight), but I think it is worth it, at least for my target. Perhaps if your target is a local app in a region that doesn’t have very good connectivity, Angular or React is not your choice. For this app, it is only useful in Metro Vancouver and the service is good across multiple providers. But that is your choice to make. I will also find a template that I can use that is ready for my business logic. I don’t have an eye for colors and site design, so I prefer buying a template whenever I make any kind of web app.

At the end of this, I hope that I have learned lots of new things and that I have a number of functioning apps. If they turn out ok, I will submit them to the store for publishing.

Time to start work!

p.s. this will take a while to complete!

New Xamarin Docs

If you have been working with Xamarin for a while then you are probably familiar with the site https://developer.xamarin.com and haven’t been there in a while, you are in for a treat. The docs have been migrated to the new Microsoft Documentation Platform.

The new platform is great. Pretty much every technology that you would want to work with is here. In this case we go to the Xamarin section and we have all the docs handy. Lets dive into the “Getting Started” document.

2018-04-27_15-14-23

 

Inside each of the documents the page is divided into three columns. The left column is a table of contents for the current document and the right hand column contains indexes into the sections of the current page. The middle column has all the information.

doc page

One of my favorite features is at the very bottom of the left hand column. If you are traveling and are going to be offline for a while, there is a link there that will create an offline pdf file that you can download to your own computer. I use it every time I fly somewhere.

Also, if you feel like contributing, there is a link at the bottom to take you to the GitHub repo where you can submit issues with the documentation and even submit new articles and updates. If you are so interested, make sure to read the contribution guidelines first!

 

VSTS and Automating Signing

Welcome

Happy new year everyone! Hopefully everyone had a good holidays (if that is your thing) and have come back refreshed, relaxed and ready for a new year. For my first post of 2018, I was going to switch it up from development and go into a bit of dev ops.

I was fortunate to see Donovan Brown present earlier this week at Microsoft Vancouver. It was a great presentation and demo and left me inspired to put some of those lessons to good use with one of my current projects, a .NET desktop addin.

Background

I am using Visual Studio Team Services Online for hosting my code repos, managing my backlog and bugs, but I haven’t made much use of the build systems. Setting up a build definition to build and run my unit test was pretty easy, and I was able to just use defaults for the most part.

But I had some struggles with how to automate the signing of the binaries. Afer doing some research on it, here is what I found and what worked for me.

Step 1

First we need to create a script of some kind to perform the actual signing of the files. I chose to use Powershell as I have never really worked with it before. In my Visual Studio solution directory I created a “build” folder and added the script there.

param($certFile, $pw, $buildDir)

Write-Host "****************************************"
Write-Host "****************************************"
Write-Host "*** S I G N I N G O U P U T ***"
Write-Host "****************************************"
Write-Host "****************************************"

Write-Host $buildDir
Write-Host $certFile

$exe = Get-ChildItem -Path "C:\program files (x86)\Windows Kits" -Recurse -Include signtool.exe | select -First 1
Write-Host $exe

$timestampUrl = "http://timestamp.comodoca.com/rfc3161"

ForEach ($file in (Get-ChildItem $buildDir))
{
  if ($file.Extension -eq ".dll")
  {
    Write-Host $file.FullName
    &$exe sign /f $certFile /p $pw -tr $timestampUrl $file.FullName
  }
  elseif ($file.Extension -eq ".exe")
  {
    Write-Host $file.FullName
    &$exe sign /f $certFile /p $pw -tr $timestampUrl $file.FullName
  }
}

So what is happening here? First thing is that this script takes three parameters:
– the location of the certification file
– the password for the certificate
– the build directory

We will look at how we get those parameters later during the task.

The first important thing the script does is locate the signing tool on the build agent. We know that it will be somewhere under the “C:\program files (x86)\Windows Kits” subdirectory, so we use the Get-ChildItem to recurse through that directory and return the first one it finds. It stores that location in a variable to be used later.

The next thing it doesis loop through the build directory for all of the .exe and .dll files. For each that it finds, it uses the sign tool, and the supplied certificate path and password to perform the signing.

The nice thing about the script above is that there is nothing in there that is project dependant. You can use this script on all of your projects.

Step 2

Next I had to upload my code signing certificate to VSTS. This is pretty easy to do, all you have to do is click on “Build and Release” on your menu, then click on “Library” and then “Secure Files”. Finally click on “+ Secure file” and upload your certificate.

codesignUploadSecureFiles

Step 3

Head over to your build definition by clicking “Builds” and then “Edit” from the build definition menu.

We are going to add a new task called “Download secure file”. You can give the task some kind of descriptive name, and then from the “Secure File” combo box, select your code signing certificate. I placed this task after the Test task.

codesignDownloadSecurefileTask

Now, if your tests pass, the build process will download the code signing certificate to your build host (either online or local). You should note that the build agent will clean up after itself.

Step 4

You need to add your certificate password to the list of variables for the build definition. In your build definition, click on variables and then “add” in the “Process Variables” group. Give your secret a name and provide the value. Don’t forget to click on the padlock to hide the value.

Once you save the build definition, the secret value is hidden. From the capture above you can see that I am unlocking my password and it doesn’t show the value.

Step 5

Finally, we just need to execute the script as a task in the build. Add a powershell task after the “download secure file” task that you created in step 3. You can make the type “File Path” and browse to the build script that we created in step 1 (remember to check it in). Next we need to add the arguments that the script is expecting.

codesignpowershellscript

Certificate file

The download secure files tasks dumps the files into the build agent work folder _temp directory. So the first parameter is “$(Agent.WorkFolder)_temp\CodeSigning2019.pfx”

Password

The process variable contains our password, and to reference it as a parameter for our script, we uses “$(pfxpassword)”. “pfxpassword” is the name in my build definition.

Build Output Directory

Finally we need to specify where the files that are to be signed are located. We use another built in variable. For my build definition it looks like this: “$(Build.SourcesDirectory)\SbSol\StructureBuilder\bin\release”

Setup Complete

And that is it. Now when your build is run, you should see the following output in the logs.

codesignbuildlogoutput

You can see where the script is started, it is the blue line. Notice that the password has been blanked out on the command line. You can see next that it is showing the location of the build directory and the certificate file and even the signtool.exe that it found on the build machine. Next you can see it looping through all of the output files and the output of the signing operation.

Wrapping up

That is how I did it. Seeing as I use Visual Studio for building my Xamarin Forms apps as well, I could probably do something similar to sign that output.

Using IValueConverter

I was down in Las Vegas all of last week for the Autodesk Forge DevCon and Autodesk University: a full four days of learning about all of the up and coming Autodesk products and technologies and networking. Lots of fun, lots of new people to talk to. I had a chat with a somewhat new’sh dev and he was complaining about the difficulties of using XAML. We delved into a bit of MVVM and he wanted to know, in effect, how to bind visual properties.

From there we went to the use of value converters and all the potential they have for presentation without having to embed visual elements and other complex logic into your view model. And it is available across WPF, UWP and Xamarin Forms.

A Simple Case

My first value converter was in WPF and making visual elements visible or not based on a value in my view model. Lets pretend we have some additional controls in our window that are only visible if the user is an accounting user. In our view model, it is a bool property named IsAccounting. If we try to bind the IsAccounting property to the control Visibility property, a binding error occurs that says the type of the value is incorrect for the target property: because of the error we won’t see the UI change.


<!-- fails -->
<TextBox Text="{Binding AccountCode}" Visibility="{Binding IsAccounting}" />

We need a value converter that will change the bool value to a Visibility value.


public class BoolToVisConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool v = (bool) value;
        return v ? Visibility.Visible : Visibility.Collapsed;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

To use it, make sure that you have the namespace that the value converter resides in declared in your Window XAML and then the converter itself referenced in the resource dictionary:

xmlns:local="clr-namespace:Demo"
<Window.Resources>
    <ResourceDictionary>
        <local:BoolToVisConverter x:Key="boolVisConverter" />
    </ResourceDictionary>
</Window.Resources>

Finally you add the converter to the binding expression of the control:


<TextBox Text={Binding SecretAccountCode} Visibility={Binding IsAccounting,Converter={StaticResource boolVisConverter}}" />

And the application looks like this:

2017-11-19boolvisconverter

I like this because it keeps the app logic free of the presentation code, and this makes your view model simpler, testable and portable.

Something More Powerful

Let’s take a look at where the IValueConverter can really help. In this example we will change the color of the text in a textbox based and an image based on the selected item in a combo box. I setup an enum with some employee types:

public enum EmployeeTypeEnum
{
	CEO,
	VicePres,
	EngDirector,
	Engineer,
}

and added EmployeeTypes and SelectedEmployeeType properties to the view model.


/// initialize this collection in the constructor with the enum values.
public ObservableCollection<EmployeeTypeEnum> EmployeeTypes { get; private set; } =
    new ObservableCollection<EmployeeTypeEnum>();

private EmployeeTypeEnum _selectedEmployeeType = EmployeeTypeEnum.CEO;
public EmployeeTypeEnum SelectedEmployeeType
{
    get => _selectedEmployeeType;
    set => SetProperty<EmployeeTypeEnum>(ref _selectedEmployeeType, value);
}

Here are our value converters, one of them will convert the SelectedEmployeeType value to a foreground color and the other will convert the SelectedEmployeeType value to an image.

public class EmployeeColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        EmployeeTypeEnum empType = (EmployeeTypeEnum) value;
        switch(empType)
        {
            case EmployeeTypeEnum.CEO:
                return Brushes.Aqua;
            case EmployeeTypeEnum.EngDirector:
                return Brushes.Green;
            case EmployeeTypeEnum.Engineer:
                return Brushes.Red;
            case EmployeeTypeEnum.VicePres:
                return Brushes.Blue;
            default:
                return Brushes.Black;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

public class EmployeeImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        EmployeeTypeEnum empType = (EmployeeTypeEnum) value;
        switch (empType)
        {
            case EmployeeTypeEnum.CEO:
                return new Uri("/ceo.png", UriKind.Relative);
            case EmployeeTypeEnum.EngDirector:
                return new Uri("/director.png", UriKind.Relative);
            case EmployeeTypeEnum.Engineer:
                return new Uri("/engineer.png", UriKind.Relative);
            case EmployeeTypeEnum.VicePres:
                return new Uri("/vicepres.png", UriKind.Relative);
	    default:
	        return null;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Add our converters to the resource dictionary:

<local:EmployeeColorConverter x:Key="empColorConverter" />
<local:EmployeeImageConverter x:Key="empImageConverter" />

The markup for our XAML looks like this


<ComboBox ItemsSource="{Binding EmployeeTypes}" SelectedItem="{Binding SelectedEmployeeType}" />
<TextBox Text="{Binding SelectedEmployeeType}" Foreground="{Binding SelectedEmployeeType,Converter={StaticResource empColorConverter}}" Margin="0,2" />

<Image Width="48" Height="48" Margin="4" Source="{Binding SelectedEmployeeType,Converter={StaticResource empImageConverter}}" />

And that is it. We have a simple and portable view model that can be used on other platforms.

2017-11-19_6-35-24

Feel free to check out the sample code in GitHub.

I also would like to give a shout-out to SyncFusion as I used their free MetroStudio icon generator to build my icons.