Saturday, December 9, 2017

Visual Studio for Mac installer crashes

There are some reports of VS for Mac crashing during install. I got to experience this first hand this weekend. The solution for me was to fire up the terminal and run the installer using sudo.

Step 1


Given that you have the installer image mounted and a terminal running.
Navigate to /volumes/Install Visual Studio for Mac.app/contents/MacOS

Step 2


Run "sudo ./Install_Visual_Studio"

Friday, October 20, 2017

Android 8 and condition `ji' not met

A quick tips/workaround. I'm sure Xamarin will address this issue shortly.

Problem


The app crashes on start up on Android 8 with the error message

[] * Assertion at /Users/builder/jenkins/workspace/xamarin-android/xamarin-android/external/mono/mono/mini/mini-arm64.c:878, condition `ji' not met


Updated solution (the real solution)


It was actually the usage of the dynamic keyword that caused the crash...

Solution (kept for historical reason)


Uncheck "Use Shared Mono Runtime" under "Android Build".

Monday, September 11, 2017

WebView blank in Xamarin Forms on UWP

TLDR;

If you are hooking up events for a Xamarin Forms WebView, wrap the hooking up in a Device.BeginInvokeOnMainThread if you experience a blank WebView. I've seen this issue mostly on UWP.

    public MyView()
    {
        this.InitializeComponent();
       
        Device.BeginInvokeOnMainThread(() =>
        {
            // Hook up events in here
            this.myWebView.Navigating += async (s, e) =>
            {
                // Do stuff here
            };
        });
    }

Longer version

I have a login view in my app and the code looks like this.

    public partial class LoginView : ContentPage
    {
        public LoginView(LoginViewModel vm)
        {
            this.InitializeComponent();
            this.BindingContext = vm;

            this.LoginWebView.Navigating += async (s, e) =>
            {
                this.BusyLabel.IsVisible = true;
                await vm?.Navigating(e.Url);
            };

            this.LoginWebView.Navigated += async (s, e) =>
            {
            
                this.BusyLabel.IsVisible = false;
            };
  
        }
    }

I needed to hook up the Navigating and Navigated events for two reasons;
  1. To display a busy/loading label over the webview
  2. To pass the resulting URL back to the ViewModel
This works... Most of the time. But sometimes the WebView just displays a white square. I tried a bunch of different urls trying to determine if it was something in the html that was messing something up. 

Then I read this post (https://forums.xamarin.com/discussion/63280/xamarin-forms-webview-does-not-work-once-the-navigating-eventhandler-is-setup). It wasn't really about this issue but the title of the post made me think.

Perhaps, if I delay the event hooking-uping it might magically work again. 

So I wrapped the hookups in a Device.BeginInvokeOnMainThread(...) call and it just seems to work.

An other related issue you might experience is this. But this goes for all controls, not only WebView.
  • https://stackoverflow.com/questions/34330446/xamarin-forms-webview-not-showing-up


Sunday, September 10, 2017

Mapping without Automapper

I've tried AutoMapper on numerous occasions and it's a great product. However, my mind seems to work a little bit different so I usually use a little different approach. I want to be able to follow my mappings so what I end up doing is to write the mappers by hand. (#bad)

I do give AutoMapper a try from time to time, but I still favour this way of doing it. It's just a personal preference!

If you haven't heard of Automapper, check it out at http://automapper.org/ before you embrace this technique! :)

The pattern I use for this is simple (and the magic lies in the simplicity of it).

Step 0 - Define the types on each side of the fence


Investigate the types you want to map. I have two ducks.

    public class BackendDuck
    {
        public int Id { getset; }
        public int BeakSize { getset; }
        public string TotallySecretDuckKey { getset; }
    }

    public class FrontEndDuck
    {
        public int Id { getset; }
        public int BeakSize { getset; }
    }

Step 1 - Create the mapper class


I create a static Mapper class that will handle my mappings.

   public static partial class Mapper
   {
   }


Why partial? Because I like to keep the option open to create another file to append to this mapper class. The file on disk could be called DuckMapper.cs. Then why isn't the class called DuckMapper.cs? Because we really don't want to check fifteen different classes to find the correct mapper. The answer is within step 2.

Step 2 - create the map methods:


Create two methods, both called Map (this is important), with the signature below.

    public static partial class Mapper
    {
        public static IEnumerable<FrontEndDuck> Map(IEnumerable<BackendDuck> source)
        {
            return null;
        }

        public static FrontEndDuck Map(BackendDuck source)
        {
            return null;
        }
    }

We always want two methods, one to Map an IEnumerable and one to map an item.

Step 3a - implement the map methods (non-linq way):


The first way of implementing the methods is by not using Linq. It's the straight forward, C# way to do it. No surprises at all.

    public static partial class Mapper
    {
        public static IEnumerable<FrontEndDuck> Map(IEnumerable<BackendDuck> source)
        {
            var result = new List<FrontEndDuck>();

            foreach(var item in source)
            {
                result.Add(Map(item));
            }

            return result;
        }

        public static FrontEndDuck Map(BackendDuck source)
        {
            return new FrontEndDuck()
            {
                Id = source.Id,
                BeakSize = source.BeakSize
            };
        }
    }

Step 3b - implement the map method using Linq


This does the same thing, but the looping part is hidden in a .Select extension method.

    public static partial class Mapper
    {
        public static IEnumerable<FrontEndDuck> Map(IEnumerable<BackendDuck> source)
        {
            return source.Select(x => Map(x));
        }

        public static FrontEndDuck Map(BackendDuck source)
        {
            return new FrontEndDuck()
            {
                Id = source.Id,
                BeakSize = source.BeakSize
            };
        }
    }

Step 4 - usage


This is how you would use the Mapper.

    public class DuckManager
    {
        public void DoStuff()
        {
            // Create a single duck
            var backendDuck = new BackendDuck() 
            { 
                Id = 1
                BeakSize = 42
                TotallySecretDuckKey = "TheKey" 
            };

            // Add the duck to a list
            var backendDucks = new List<BackendDuck>()
            {
                backendDuck
            };

            // Use the mappings - if setup correctly, 
            // all you have to remember is Mapper.Map(...)
            var item = Mapper.Map(backendDuck);
            var list = Mapper.Map(backendDucks);
        }
    }

Summary


Pros:
  • It's easy to follow debugging
  • You get all your mappings written in C# code that you can follow, nothing is hidden
  • Written correctly, just remember Mapping.Map( ) and you are set
Cons:
  • More code to write

Resources


Check out Automapper if you haven't done so. It might fit your needs better.

Saturday, September 9, 2017

RFLCT_Ambiguous when running UWP in release and using Autorest

This is one of those short stories...

TLDR;


If you get a RFLCT_Ambigous exception in your UWP app in Release configuration on the initialization of the autogenerated service client that Autorest created for you then simply update the Microsoft.NETCore.UniversalWindowsPlatform package.

The issue does not arise in debug mode.

Long version


I'm ashamed... I spent way to much time on this issue before I tried what I should've tried the first time I saw the error. 

Always update your nuget-packages before trying to solve an issue related to some other persons code. Oh, and always do so in a feature/bug branch or at least make sure you can roll stuff back. Things can go bad.

The issue at hand by the way was that some Attributes had been duplicated. And if you try to get an attribute by doing something like this:

 GetCustomAttribute(typeof(AssemblyFileVersionAttribute))

It might actually return multiple attributes. And a piece of code inside Microsoft.Rest.ClientRuntime didn't like this. It seems like attributes that makes no sense duplicating has been duplicated, like AssemblyFileVersion... Why would you like to have two of those.

Anyhow... I'm going to write a couple of hours of my clients bill now and tattoo "always update nuget packages first" on a close by colleague so I will remember it in the future.


Resources / sources


https://github.com/Azure/autorest/issues/1542

https://github.com/aspnet/EntityFrameworkCore/issues/6242

https://github.com/dotnet/corefx/issues/16769

Tuesday, September 5, 2017

Injecting a new root element in a Xamarin Forms Content Page

If you want to insert a new root element on a content page (using Xamarin Forms) you must set the Content to null first before assigning it again. Otherwise touch events will not register (at least not on iOS).

For example, add the entire view in an AbsoluteLayout could look like this:

 // Get a reference to the content
 var content = page.Content;
 page.Content = null// This line is key

 // Create a new root element and add the content
 var absoluteLayout = new AbsoluteLayout();
 absoluteLayout.Children.Add(content);

 // Replace the content
 page.Content = absoluteLayout;

I would do this directly after the call to InitializeComponent() in the code behind of the view.


Friday, August 25, 2017

Visual Studio grinds to a halt when upgrading a netcore website

This cost me the better part of a day to investigate since I tried everything else but recreating the project.

How I messed up


I had an ASP.NET Core WebApi project that I simply upgraded to .NET Core 2.0 by changing a line in the configuration from

<TargetFramework>netcoreapp1.1</TargetFramework>

to

<TargetFramework>netcoreapp2.0</TargetFramework>

What happened


Visual Studio (2017) pretty much hanged and/or performed extremely slowly. When loading the solution VS took about 2 minutes to load the web project.

How did I resolve it


Simply recreate the web project (with 2.0 selected) and import all files to it again. Pay a little notice to the startup.cs file. You might find some small changes there so don't just overwrite it.

Thursday, August 17, 2017

Popped Pages in Xamarin Forms

This post is long overdue. About a year ago (July 2016) I managed to get some code into Xamarin Forms Core. This code change was necessary in order to make TinyPubSub work correctly.

TLDR;


If you call Navigation.PopToRoot() in Xamarin Forms and want to know all the pages being popped you need to cast the NavigationEventArgs to a PoppedToRootEventArgs.

    var page = new NavigationPage();
     page.PoppedToRoot += (object sender, NavigationEventArgs e) => 
     {
         // Typecast the args
         var args = e as PoppedToRootEventArgs;

         // Get the pages
         var poppedPages = args.PoppedPages;
     };

Long story


There was quite a long discussion before I got this change approved by Jason Smith and the Forms team. The most pressing issue was that we could not break the signature of the PoppedToRoot event so we ended up creating a new event args class (called PoppedToRootEventArgs) and simply passed that one in. 

This of course hides the PoppedToRootEventArgs from plain sight so you need to know what you are looking for.

The internal workings of PopToRoot (the important parts) looks like this:

    var args = new NavigationRequestedEventArgs(RootPage, animated);

     EventHandler<NavigationRequestedEventArgs> requestPopToRoot = PopToRootRequested;
     if (requestPopToRoot != null)
     {
         requestPopToRoot(this, args);

         if (args.Task != null)
             await args.Task;
     }

    PoppedToRoot?.Invoke(thisnew PoppedToRootEventArgs(RootPage, childrenToRemove.OfType<Page>().ToList()));
        

The last line is the event (PoppedToRoot) and as you see we pass in PoppedToRootEventArgs as the args.

The PoppedToRootEventArgs is simply a class inheriting from NavigationEventArgs that adds PoppedPages as a IEnumerable to the class.

    public class PoppedToRootEventArgs : NavigationEventArgs
    {
        public PoppedToRootEventArgs(Page page, IEnumerable<Page> poppedPages) : base(page)
        {
            if (poppedPages == null)
                throw new ArgumentNullException(nameof(poppedPages));

            PoppedPages = poppedPages;
        }

        public IEnumerable<Page> PoppedPages { getprivate set; }
    } 

Thursday, July 20, 2017

TinyPubSub makeover - arguments and new super hero publish features

I finally got around to give TinyPubSub a well deserved make over by adding some features that have been requested for a while. The toughest part is to keep it Tiny and not add to much bells and whistles to it.

I also got some great help from my friend Daniel Hindrikes to set up a devops flow that will help me manage pull requests and nuget-package publishing.

The features added to this version are;

  • Publish with arguments
  • Publish using fire-and-forget (with or without argument)
  • Publish async (with or without argument)

Publish with argument


You can now subscribe and pass an argument of the type Action<string>:

  TinyPubSub.Subscribe("test", (x) => Log.WriteString(x));

And publish it by simply adding another argument:

  TinyPubSub.Publish("test""duck");

In order to keep it tiny we only allow for a single string argument at the moment. We did explore a whole bunch of alternatives, including generics and dynamic objects and stuff but we settled for this at the moment.

Publish using fire and forget (PublishAsTask)


Using a simple Publish in TinyPubSub is synchronous and will stop the execution flow until all the subscribers have executed their code. We've now added a way to publish events fire-and-forget style.

  TinyPubSub.PublishAsTask("test""duck");

Publish async


And the last way is to simply publish async. Works as expected.

  await TinyPubSub.PublishAsync("test""duck");

Resources

Sunday, March 12, 2017

Xamarin for the non-xamarinist

 A Xamarin introduction

This is a post about some facts you need to know to get started with Xamarin development. It's not code centric so the target audience would be someone who's interested in the basic Xamarin facts.

We assume that the target platforms are iOS and Android. It’s worth pointing out that Xamarin (and especially Xamarin Forms) can target Windows Phone, Windows Desktop Apps and Mac OS X apps as well.

Specific requirements for iOS

Apple requires that all iOS apps are built on OS X which in turn only can run on Apples hardware. This means that you must have a Mac to build iOS apps. Xamarin also uses the XCode toolchain for compiling the app,
There are some approaches to this:
  • The first hand recommendation is to use a MacBook (Air/Pro) with Parallels Desktop (virtualization software) to run Windows on the same machine. This allows for a seamless transition between OS X and Windows, enabling the developer to use Visual Studio to develop iOS apps.
  • The second hand recommendation (perhaps in combination with the first recommendation) is to acquire a Mac Mini as a local build server. A windows client can connect to this build server and send all iOS builds to it. There is also the possibility to remote access the simulator directly from within Visual Studio. If you have a Windows computer (like a SurfaceBook) you also get multipoint touch in the simulator.
  • Another option for build is to use Visual Studio Mobile Center (currently in preview) to take care of the builds for you. It’s a wrapper on top of multiple Azure services.

 Xamarin Forms or Traditional Xamarin development

One thing you have to do early in the project is to get a good grip of the difference between Xamarin Forms and Traditional Xamarin development.

Xamarin Forms is a GUI abstraction that renders fully native user interfaces. It allows for a shared GUI codebase with the drawback of pixel perfect designs.

Traditional Xamarin Development is best if you have a lot of differences between the platform user interfaces or simply like storyboarding and axml.

Regardless of which approach you take you should strive for moving as much of the logic away from the GUI and into shared code base as possible.

Xamarin Forms

Xamarin Forms is a platform on top of Xamarin that abstracts the GUI-code (Xaml or C#) but still renders 100% native user interfaces.

It is very possible to make beautiful apps in Xamarin Forms but it still requires that you have knowledge about the underlying platform. You also have to ability to drop down into platform specific code at any moment. Especially through the user of Dependency Injection which plays a vital role in a cross platform mobile architecture . You also have the ability to create separate views for each platform even if you declare them in the shared library.

The most common architecture to use when writing a Xamarin Forms application is MVVM. There are a lot of tooling and resources available.

The basic idea in forms is that you declaratively define you UI using XAML or C#. Most common is to use XAML. For example, a button in XAML could look like this: <Button Text=”My Button” />. When this renders (or compiles if you use Compiled Xaml) this is turned into a UIButton on iOS and a Button on Android. The conversion between abstract and concrete classes is done by the concept of Renderers. Every renderer can be extended or replaced. You can also write your own renderer. There is no hidden magic.

And it’s all open source.

Traditional Xamarin Development

In traditional development you define the GUI in the same way that you do it when developing apps using the vendor specific tooling. (Java in Android Studio or Swift/Objective-C in Xcode). On iOS that usually means Storyboarding and on Android you are most likely defining the GUI in axml-files. You could also write it using C#, but it tends to be a lot of code to write.

You can still (and should) choose to use an MVVM-framework to move all the common code out of the views.

UI Testing

When it comes to Android specifically, UI Testing is a must and it’s highly recommended that you find some tooling that helps you with this.
Xamarin Testcloud is one of those tools/services that allows you to run your app on thousands of hardware devices with the weirdest combination of OS versions installed. You simply cannot do this in an affordable way yourself.

You author your tests locally first, in code or with a test recorder. Then you submit the tests and a build to TestCloud and select what devices you want to run it on. You pay by the device minute used.

It also works perfectly for iOS and even for apps that aren’t written in Xamarin at all.

The other great benefit of Testcloud (or services like Testcloud) is that you can recreate bugs on the actual device/OS combo that the bug was spotten on without having to buy that specific device.

Architectures and plugins

This is the current list of components/nuget-packages/services that I currently recommend using in a Xamarin App.
·       Autofac – Dependency injection.
·       MVVM – I often use Vanilla MVVM with a simple base class for the most common stuff..
·       PropertyChanged.Fody – IL injection (weaving) of INotifyPropertyChanged. ViewModels get’s a lot smaller and code readability increases.
·       Acr.Dialogs – An abstract way to use common system dialogs (think UIAlert etc.)
·       Akavache – Cache amd SQLite databas packaged for Xamarin. Also supports secure and encrypted app based storage.
·       HockeyApp – Error tracking and usage tracking.
·       Newtonsoft – Json serializer
·       TinyPubSub – Very simple PubSub handler for internal communication.
·       Xam.Plugin.Connectivity – Plugin for handling network changes
·       Xam.Plugin.Geolocator – Plugin for handling GPS
·       Xam.Plugin.Media – Plugin for handling camera and media
·       Xam.Plugin.Settings – Cross platforms settings
·       Xam.Plugin.Vibrate – Plugin for handling vibration
·       ZXing.Net.Mobile – Bar code scanner if one should be needed.