Xamarin Forms: iOS and SIGABRT

Introduction

I have been working on a new project, one that involves Xamarin Forms and communicating with IOT devices over BluetoothLE. BluetoothLE is a very new thing for me, and I have been struggling a bit with getting it setup.

Plugin

Before I go into the SIGABRT issue, I want to give a shoutout to Allan Ritchie @aritchie for his bluetoothle plugin. I have definitely learned a lot from it.

SIGABRT

Did I mention that I am not that familiar with iOS dev work? Or Apple for that matter? When starting up my application, it crashed the moment I tried to access the BLE adapter with this message:

Got a SIGABRT while executing native code. 
This usually indicates a fatal error in the mono runtime or one of the native libraries.

I had no idea what this actually meant. I had the above library sample app and it worked fine. I did some digging and found a post on the Xamarin Forms forums which said this usually corresponds to a privacy issue. And you can use the device logs to figure out which one. I wish I had kept that post so I could attribute it better.

I am using Visual Studio, so in the View | Other Windows there is a Device Log that will give you a view into your device. Be aware, it is literally a fire hose: stop and clear the log before you start your app and it will hopefully reduce some of the clutter.

I did find out that it was indeed a permission issue! I needed to add NSBluetoothPeripheralUsageDescription key and text prompt to the info.plist file. Once added, I was back in business.

Platform Services: Part 2

Hello from Las Vegas! I am down in Las Vegas for the Autodesk Forge DevCon and Autodesk University. A total of four days of an absolute fire hose of information and learning! I have a few minutes of downtime and I wanted to provide an update on the new direction of consuming platform specific services in your portable project.

In my original post, I showed you how Prism would use the Xamarin Forms built in dependency service to resolve an object if it couldn’t find it in the container that Prism uses. That was the accepted practice for version 6.3 and earlier, but now, in the upcoming 7.0 release, the authors have specified that all object resolution should be done via the Prism container.

Fortunately it is pretty easy.

In Prism, there is an interface that you implement for each of your platforms: IPlatformInitializer where T is your Prism container. I typically use Unity, so my implementation would look something like this:

public class AndroidInitializer : IPlatformInitializer<IUnityContainer>
{
    public void RegisterTypes(IUnityContainer container)
    {
        container.RegisterType<IPortableInterface, DroidImplementation>();
        // other registrations
    }
}

Now you just need to pass that implementation into the LoadApplication call in the platform specific app initialization. Continuing with Android, it looks like the following:


[Activity(Label="projectname" ...)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);
        global::Xamarin.Forms.Forms.Init(this, bundle);
        LoadApplication(new App(new AndroidInitializer()));
    }
}

From there, it goes into your App object that is derived from your selected container specific PrisApplication class. The constructor takes one parameter of IPlatformInitializer which you just move along to the base constructor.


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

    /// ... rest of your implementation
}

And there you go: all of your registrations controlled directly within Prism for a one stop shop for managing them.

I will add one small caveat to the information above. I wrote most of this from memory while sitting in a hallway at the Sands Convention Center. Prism is going through a number of changes from 6.3 to 7 and I might have mis-spelled a class name. But I think it should stand up fairly well.

Xamarin Dev Days Lab – Prism Step 2

This is a continuation from the first post. You can find all of the code in my GitHub repository under step 2.

Viewmodels

I think most of us know what a viewmodel is and have an understanding of the MVVM pattern. If you don’t know, or need a refresher, there will probably be enough information in here for you to search around on.

The starter app already has one view model in it called SpeakersViewModel. You will remember it as the class that implements INotifyPropertyChanged. This interface is what tells the data binding system to update the UI, and when the UI changes, to update the property in the view model. Every view model needs to implement this interface, so right away, I hope you can see that we would like to move that functionality into a base class so as not to keep redoing it. And, as you might guess, Prism already has such a base class! I still like to make my own base class though, and include any app specific properties that I use a lot.

Below is a snippet of the SpeakersViewModel showing the implementation of INotifyPropertyChanged and how to use it from within the view model itself.


public class SpeakersViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private void OnPropertyChanged([CallerMemberName] string name = null) =>
        PropertyChanged?.Invoke(
            this,
            new PropertyChangedEventArgs(name));

    private bool _isBusy = false;
    public bool IsBusy
    {
        get { return _isBusy; }
        set
        {
            _isBusy = value;
            OnPropertyChanged();
        }
    }

    /// other properties go here
}

Let’s refactor the above view model to use the Prism helpers. First we will make our own app specific viewmodel base and derive from the Prism MVVM base class. Just for fun we will put the IsBusy property into the base class just to show the property in action.


public class BaseViewModel : BindableBase
{
    BaseViewModel()
        : base()
    {
    }

    private bool _isBusy = false;
    public bool IsBusy
    {
        get { return _isBusy; }
        set { SetProperty<bool>(ref _isBusy, value); }
    }
}

public class SpeakersViewModel : BaseViewModel
{
    SpeakersViewModel()
        : base()
    {
    }

    /// put other speakers functionality here
}

I think the above is pretty straight forward. We created a base class to hold common functionality and then redid our view model. We are still deriving from INotifyPropertyChanged (via BindableBase), and we still have the IsBusy property. If you go to the code in Step02 you can see the class in its entirety.
This brings us to our next problem: how do we get the view model instantiated in the class? In the case of the dev days sample app, it is being “newed-up” in the Page code-behind and being set manually. This is fine for very simple view models, but if we need services added to the view model, we are going to find it a bit more painful.

In the Prism world, you would let Prism take care of instantiating the view model for you, and by registering your services in the Container (see the App class), they will be added to the view model automatically. The way Prism manages this is by using an attached property. If the property is set to true, it will use a naming convention to find the view model type. Instead of using the “new” operator directly, it will use the UnityContainer to create it for you. The UnityContainer will determine (via reflection) if the view model depends on any services, and if so, inject those services into the view model for you. Once it has been created, it will attach it to the BindingContext of the page. What does this look like?

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
prism:ViewModelLocator.AutowireViewModel="True"
x:Class="DevDaysSpeakers.View.SpeakersPage"
Title="Speakers">

</ContentPage>

The important line is the one containing AutowireViewModel=”True”. First we need to setup the namespace so that we can attach the AutowireViewModel property to the page. If that value is true, the logic behind the property will use naming conventions to find the view model class and then create it and bind it. The default conventions is that all pages are stored in the “Views” folder and the view models are stored in the “ViewModels” folder. The full name of the view model will be the name of the page with “ViewModel” appended. In the above example, Views.SpeakersPage will become ViewModels.SpeakersPageViewModel.

We also need to remove the view model and binding that we did in the page code-behind. In the SpeakersPage constructor, remove everything except for the constructor. It should now look like this:


public partial class SpeakersPage : ContentPage
{
    public SpeakersPage()
    {
        InitializeComponent();
    }
}

If you were paying really close attention, you would notice that in our dev days app, we are actually using the “View” and “ViewModel” folder, so we are probably going to have to override the default functionality. There are two ways to do this: first is to override the default view model resolver function. This is a bit more involved, and I am going to look at this functionality in another blog post. The other method is to specify the view model type when you register the page for navigation. In your App.RegisterTypes function, change your SpeakersPage registration to look like this:

protected override void RegisterTypes()
{
    Container.RegisterTypeForNavigation
        <View.SpeakersPage,ViewModel.SpeakersViewModel>();
}

Now any time we navigate to the SpeakersPage, the SpeakersViewModel will be created and injected. If you run the app now, you should see that the UI looks exactly the same, and that you can click on the sync button and it displays the results on the main page.

Recap

To recap, what we have done is changed how the view models are created and made use of the Prism base view model. We also made use of the Prism technique of automatically creating and injecting the view model into the page BindingContext. Our next step will be to abstract out the the web api service that is inside the SpeakersViewModel so we can show how the dependency injection works within Prism: more importantly, it makes your app more testable and maintainable.

You can find the code under Step 02 of my GitHub repository.

Xamarin Dev Days Lab – Prism Step 1

One of the goals that I gave myself this year was to start improving on my public speaking. It is something that I often find difficult and I wished to improve. So earlier this year, I did a presentation to the Vancouver Windows Platform Development meetup group, and it was on developing a UWP app with a hamburger style menu and using the Prism framework.

I think it went pretty well, and I learned a lot, and not just on public speaking. Giving the presentation meant I had to dig into the framework more than I normally would to learn why things were done a certain way, and how they were done. There is a lot of great stuff to learn in Prism.

I had used Prism previously for regular WPF desktop apps before and was pretty happy with it. If you are unfamiliar with the library, here is an abbreviated history: it was started by the Microsoft Patterns and Practices Teams as a WPF library to help show developers how to architect apps in a modular and maintainable manner. Along the way it added support for Silverlight, Windows Phone and Windows Universal. After version 5, it was released out into the community to maintain and enhance. Silverlight, Windows Phone and Windows Universal were dropped and Universal Windows Apps and Xamarin Forms were added. In addition to keeping your app maintainable, it also helps out with common patterns such as MVVM, messaging, logging and dependency injection. It also helps out with platform specific things such as navigation.

I have had the idea of doing a series of posts on using Prism with Xamarin Forms for a while now, and was stuck on a suitable demo project. During the Xamarin Dev Day hands on lab, I came up with the idea of converting that app into a Prism app. At first, I will stick to the basics and then maybe follow up with some more detailed posts on specific subjects such as navigation and view model injection.

The first thing we are going to do here is take the dev days sample app and build it up to where it gets the list of speakers and shows the details of the selected speaker. I have it setup in the following repository https://github.com/MichaelPonti/XamarinPrism under DevDaysSpeakers. If you clone the repository, restore packages and build the droid app, you should be able to load the list of dev days speakers and navigate to their detail page.

Note: I am just going to stick to the droid project and not show iOS or UWP.

Next what we will do is add in the nuget packages for Prism and then fix up the App object.

When using Prism, your first need to decide what kind of dependency injection you are going to use. I always seem to default to Unity: it was the first container that I had used and has always worked well for me. Out of the box, Prism comes with Unity, Ninject, AutoFac and DryLoc. Pick the one that you like and go with it, or, use something else if you want to put in a bit of extra effort. Let’s add Prism.Unity.Forms as shown below:

nuget

Add nuget package to projects in solution.

Adding Prism.Unity.Forms will add in the following items to your projects:

  • Prism.Unity.Forms
  • Prism.Unity
  • Prism
  • Microsoft.Practices.Unity
  • Microsoft.Practices.ServiceLocation

Now that we have Prism installed in the app, let’s setup our App object (located in the shared portion of the solution). If you were at one of the dev days, or have done any Xamarin Forms in the past, you know the app class is the main entry point. Each of the platform specific projects will jump into the app object to get at the cross-platform code.

The easiest thing to do is to just comment out the existing class and replace it with the following:


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

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

    protected override void RegisterTypes()
    {
        Container.RegisterTypeForNavigation<View.SpeakersPage>();
    }

    protected override void OnSleep()
    {
        base.OnSleep();
    }

    protected override void OnResume()
    {
        base.OnResume();
    }
}

So what do we have up there? Use the OnInitialized to handle tasks once the App is up and running. At the very least, we are going to navigate to the first page here. The other important piece is the RegisterTypes function. In here we will register our services and also our pages for navigation. For now, all we are going to do is register the SpeakersPage.
If you run the app now, you should find that it starts up and displays the main page. If you click on the button, that should still function as well. At this point, it will crash if we try to navigate to the details page of one of the listed speakers.

We have a pretty good start here and it is time to wrap up. I have decided to talk about the MVVM support Prism provides first instead of fixing the navigation crash. One of the nice things about Prism is that it abstracts navigation away from knowing page types and moves navigation into the view model. So we will get our view model setup first.

Stay tuned for step 02!

Xamarin Forms Maps Bits

I ran across a couple of small issues tonight with my work with the Xamarin Forms Map, and it had to do with the precision of the values that I was using for the Center property that I setup in my previous post.

Normally in the Android emulator with Visual Studio, it has a preset starting location. For my app, I wanted something a little closer to home. To get the values for the MapSpan object, I was just outputting the values for the fields from the Center property that I had setup to figure out where I wanted to start from.

When I used those values as my initial start point for the map, I was putting in the full precision that the Visual Studio debugger was showing, approximately 15 digits after the decimal place. When I started forcing these values in, the map wouldn’t update its position.

I then started to play around with the location services in the emulator and the map would update in response to those values. Looking at the values displayed by the emulator, they only used 4 digits. I made the change and everything started working again. Assuming I am in the view model and am using the attached property to bind to set the center point of the map, this didn’t work for me:


// underlying Map.MoveToRegion call doesn't do anything
Center = new MapSpan
(
	new Position(48.0111563131213188, -122.0096835170062306),
	0.0096835170062306,
	0.0111563131213188
);

Instead, try using it like this:


// underlying Map.MoveToRegion call now works
Center = new MapSpan
(
	new Position(48.0111, -122.0096),
	0.0096,
	0.0111
);

I have yet to go looking at why this is the case but it seems likely that the map control can only handle that level of accuracy. If you are finding that you can’t seem to control what the map is displaying, check out the precision of the values in the MapSpan object. And if anyone reading this knows for sure what is happening here, feel free to chime in.

I will be attending a Xamarin dev workshop at Microsoft Vancouver, perhaps there will be someone there that can answer this definitely.

Hope that helps.