Xamarin Application Architecture

In this post, I will talk about strategies for developing a cross-platform Xamarin application with focus on code sharing, increasing testability, and reducing overall development and maintenance efforts.

The application architecture is itself problem specific, but there are certain design patterns that can guide the overall structure of the application. The ones I mostly work with are Model-View-Controller, Model-View-Presenter, and Model-View-ViewModel.

MVC should be adopted for small applications or proof of concept. Since, Android and iOS both natively support MVC, it will mean less roadblocks, and faster implementation.

MVVM reduces platform specific code, and most of the logic is shared across platforms using PCLs. There are great MVVM frameworks out there that work really well with Xamarin, such as MVVM Cross, and the official Xamarin Forms.

MVVM Cross is a data driven pattern, and the presentation logic is quiet centralised. This means any upgrades to the library or to the system, can break custom navigation and screen transitions within the application. As Android and iOS platforms are constantly upgraded, with newer restrictions around security and permissions (background tasks / app permissions), and as user interface (gestures / notifications / newer design guidelines) are greatly improved, support for these can be costly in both time and effort. That being said, it is still a very powerful platform, and most applications can be written with it, with great results.

Xamarin.Forms is a UI first framework, and allows .Net developers to use their existing XAML skills for developing mobile applications. However, this platform is still maturing and needs to reach a more stable stage. Even though native controls can now be used in XAML, but one looses advantage of data binding, and the extra effort required to maintain proper navigation in the application, and catering for various screen types, out does the benefit for now.

MVP is another pattern that works really well with Xamarin cross-platform applications. It is a variant of the MVC pattern and allows full use of platform native capabilities, with great control over the UI of the application. It is the pattern of choice for native development and we will look more into it below.

MVP has 3 major components

Model: This is data that we want to show in our views. Apart from data classes, this carries responsibility for retrieving, storing, validating advanced data sets, and advanced functions such as syncing and conflict resolution, cache maintenance, offline capabilities.

View: This module is responsible for showing data to user and responding to user gestures and actions. It should only be dependent upon the presenter and native platform capabilities for styling.

Presenter: Presenter is the layer below the view and is responsible for providing data the view can use. It relies on the model layer to retrieve data, and can also publish other events to UI, such as loading data state, timeout and error state.

The golden rule of mobile development is to keep the UI layer as dumb as possible. That means UI only needs to know about its data, view transitions and animations, and publishing interaction events, such as gestures, button clicks. As mentioned view is completely dependent upon presenter, and presenter is dependent upon the view for human interaction. However, to promote unit testing for each of the modules, presenter and view need to be decoupled.

To achieve this, we can define a contract between presenter and the view. For a login screen the view’s contract can be:

and the presenter contract can be

The presenter should be platform independent so that it can be shared across different mobile platforms. This means, it does not respond to UI life-cycle methods, unless explicitly told so.

The controllers in iOS and Activities in Android are never directly created using constructor, which means that we cannot use dependency injection to provide a presenter to our view. In this scenario I like to use an anti-pattern called ‘Service Locator’.

Service locator is considered anti-pattern because of the complexities of managing dependencies, and dependency’s child dependencies. This is highly error prone, but in case of multi-threaded programs, where start of the application can run many different initialisation threads, double instance of a service can be created. This pattern works well in simple scenarios and this is exactly what we are trying to solve. A dependency service can be used to locate the presenter implementation inside the view.

If the scenario was anymore complex, it certainly means, that View has been assigned more work than it needs to perform and is against MVP principles. A sample of this is shown below

As shown above the AppDelegate in the application loads all the presenters in the application. When the view loads, it uses the service locator instance to retrieve its presenter.

By abstracting the presenter from the view gives us many advantages.

  • One presenter will not work on all devices. Such as finger print functionality for login can only be used on devices that have the required hardware. In this case inheritance can be used to create versions that can handle extra features, while having no functionality in base presenters.
  • By abstracting the creation of the presenter outside the view, allows to make our UI really passive, and thus we are able to test UI independent of any other module.
  • This method allows to create presenters that can help automate UI testing, performing common testing scenarios automatically. This can also be used for automatic product demos.

 

The above implementation of MVP suffers from one disadvantage. It ignores the asynchronous nature of the mobile applications. Both Android and iOS are quite capable devices. Even a simple Notes application performs a lot of activities when loading. These can be logging in the user, loading the notes from the cache, syncing down any notes created on other device, syncing up any notes created during offline mode, resolving conflicts, showing progress to the user, restoring state to what it was when the application was last closed. These activities can take from few milliseconds to few seconds. The longer the application takes to boot up, the higher the chance that the user will stop using the application, and will eventually remove it from the device.

Enterprise applications are much more complex. In a perfect world, they are developed using mobile-first approach. However, not all companies can follow this and instead of the application interacting with a unified set of APIs, it ends up interacting with multiple legacy systems, combine the result and then provide it to the UI layer. This means that the application load time can be really high especially if there is stale data on the device.

In such a scenario, instead of defining contracts between the presenter and view, a more reactive approach can be used. This allows us to build application with a user centric approach. This means we think of how the user is going to interact with application, and what does the user see while waiting for data to be available in the application. The code below shows this for a login screen.

The above code shows the asynchronous nature of the View, and it follows a push approach, reacting to events when raised by the presenter. This further decouple the bond between the view and the presenter allowing for easier testing, and also helps to identify real life scenarios within the app, such as data being delayed or no connectivity.

Thus, we see how MVP aims at building a very user centric app, with a very passive and light UI layer. Both iOS and Android platforms are competing to enhance user experience. In future, we can see apps that will react and adapt to user habits using machine learning. This also means that they will have to work in a stricter environment, like stricter guidelines for UI, background tasks, app permissions, reduced background tasks, and change in application notification patterns. MVP will definitely allow to handle these changes, without affecting user experience.

Xamarin Forms: Mircosoft.EntityFrameworkCore.Sqlite issue with Physical devices

Introduction

Building Xamarin Forms apps using .Net Standard 2.0 is still pretty much new to industry, we are just started to learn how differently we have to configure Xamarin setting to get it working when compared to PCL based projects.

I was building a Xamarin Forms based App using Microsoft’s Entityframeworks SQlite to store app’s data. Entity framework using sqlite is an obvious choice when it comes to building App using .Net Standard 2.0

Simulator

Works well on pretty much on all simulators without any issue, all read/write operations works well.

Issue  – Physical Device

App crashes on physical device, when tried to read or write data from the SQlite database

Error

System.TypeInitializationException: The type initializer for ‘Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions’ threw an exception. —> System.InvalidOperationException: Sequence contains
no matching element

Resolution

Change linker behavior to “Don’t Link”

Xamarin forms using .Net Standard 2.0

Introduction

All Xamarin developers, please welcome Net standard 2.0. This is the kind of class library we were waiting for all these years. The .Net standard 2.0 specification is now complete and it is included with Net core 2.0, Net framework 4.6.1 and up to latest versions. It can be used using Visual Studio versions 15.3 and up. Net Standard 2.0 obviously supports C# and also F# and Visual Basic.

More APIs

Net Standard 2.0 is for sharing code via various platforms. It is included with all the common APIs that all .Net implementations, it unified all .net frameworks to avoid any fragmentations in future. There are more than 32000 APIs in .Net Standard 2.0 most of them that are already available in .Net Framework APIs. Microsoft has made it easy to port existing code to .Net Standard 2.0. It is now easy to extend any .Net Standard to .Net core 2.0 or any versions that come in future.

NuGet Support

Most NuGet packages currently work well with .Net framework, but not all projects are compatible to move to .Net Standard 2.0, therefore a compatibility mode is added to support them.  Even after compatibility mode, only upt0 70% of packages are supported.

Frameworks and Libraries

Below is the table,list all the support frameworks and libraries. Click here for more details

.NET Standard
1.0 1.1 1.2 1.3 1.4 1.5 1.6 2.0
.NET Core 1.0 1.0 1.0 1.0 1.0 1.0 1.0 2.0
.NET Framework 4.5 4.5 4.5.1 4.6 4.6.1 4.6.1 4.6.2 4.6.1 vNext 4.6.1
Mono 4.6 4.6 4.6 4.6 4.6 4.6 4.6 5.4
Xamarin.iOS 10.0 10.0 10.0 10.0 10.0 10.0 10.0 10.14
Xamarin.Mac 3.0 3.0 3.0 3.0 3.0 3.0 3.0 3.8
Xamarin.Android 7.0 7.0 7.0 7.0 7.0 7.0 7.0 8.0
Universal Windows Platform 10.0 10.0 10.0 10.0 10.0 10.0.16299 10.0.16299 10.0.16299
Windows 8.0 8.0 8.1
Windows Phone 8.1 8.1 8.1
Windows Phone Silverlight 8.0

Sample to convert PCL or Shared to .Net Standard 2.0

  1. Create a default PCL or Shared based Xamarin Forms applications and name it appropreately and wait for solution to loadScreen Shot 2017-12-09 at 09.18.05
  2. Add .Net Standard class library by selecting .Net Standard 2.0Screen Shot 2017-12-09 at 09.24.38Screen Shot 2017-12-09 at 09.25.41Now project should look something like belowScreen Shot 2017-12-09 at 09.26.38.png
  3. Now remove PCL or Shared based project (VERY Important only after moving all the required project files to Netstandard20Test library) and compileScreen Shot 2017-12-09 at 09.28.38.png
  4. now rename the NetStandard20Test to NetStandardTest (Same as deleted library), make sure to rename DefaultNameSpace and Assembly to NetStandarTestScreen Shot 2017-12-09 at 09.30.07Screen Shot 2017-12-09 at 09.30.14Screen Shot 2017-12-09 at 09.30.24Screen Shot 2017-12-09 at 09.30.44Screen Shot 2017-12-09 at 09.34.23.png
  5. Now build the project and see if build is successfully.
  6. Your build should fail with errors as shown below, it is because of the deleted project, now we have to reference back the newly created .Net Standard 2.0 to both Android and iOSScreen Shot 2017-12-09 at 09.35.53.png
  7. Now edit references on each platform project to add newly created project as shown below onceScreen Shot 2017-12-09 at 09.37.58Screen Shot 2017-12-09 at 09.38.05
  8. references are applied correctly, you should get below errorsScreen Shot 2017-12-09 at 09.52.14
  9. Now add Xamarin.Forms NuGet package for all projectsScreen Shot 2017-12-09 at 09.54.04.png
  10. Now build the project and you should see any errorsScreen Shot 2017-12-09 at 10.58.06
  11. Microsoft has also released a compatibility NuGet package that makes sure’s all the existing packages are compatible to .Net Standard 2.0
  12. Add NuGet package, Mirosoft.NETCore.Portable.Compatibility to .Net Standard 2.0 project.Screen Shot 2017-12-09 at 11.03.01

Hope this blog is useful to you.

 

Inter-App Communications in Xamarin.iOS and Why OpenUrl Freezes for 10+ sec

Inter-App Communications

Mobile apps are meant to communicate using multiple channels, but the most popular, recommended, and widely used is using Scheme Uri. If you have not used Scheme URI then you should consider adding them to your app, it takes less than a minute to add support to your app, and it provides you a great way to get users to your app.

Setting the Stage

One scenario that I had was App A was launching App B and querying data, App B was in turn looking up the request, and returning data to App A. This is a common practice and can be seen in the diagram below.

Scheme uri ios

Scheme uri ios

The Investigation

The problem here was that App B was freezing for up to 10+ sec before returning the result to App A. At first, I thought that this might be because the app initialisation or the data lookup taking long time, so I added diagnostic trace statements like below to time the operation and see where the time is spent.

public class AppDelegate
{
	...
	
	public override bool FinishedLaunching(UIApplication app, NSDictionary options)
	{
		Console.WriteLine("FinishedLaunching started: " + DateTime.Now.ToString("F"));

		...
		
		Console.WriteLine("FinishedLaunching complete: " + DateTime.Now.ToString("F"));
	}

	public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
	{
		Console.WriteLine("OpenUrl started: " + DateTime.Now.ToString("F"));

		...
		

		Console.WriteLine("OpenUrl complete: " + DateTime.Now.ToString("F"));
	}
}

I found that my app was starting in less than 1 Sec, which is quite impressive, and I am very happy about 🙂 but the problem was in returning the data to the launching app (App A). The traces were like these:

Launch Services application launch failed - timeout waiting - Trace logs

Launch Services application launch failed – timeout waiting – Trace logs

This is telling me that App B was not able to launch App A to return back the data, which was quite surprising. I found that if you move that code to your pages/viewControllers things work fine. I thought that this was a bizarre situation, then I found this StackOverflow post, which explained the problem.

The Solution

Apparently, the iOS was having a race-condition like in trying to launch an app while the app itself was not fully launched. So the suggested solution was to add some delay or run it on another thread. Running the launch of App A on another thread would not work as it needs to be on the mainUiThread, so here is the solution I came up with:


public class AppDelegate
{
	...
	
	public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
	{
		// handle opening url and look up data

		...

		Task.Delay(500).ContinueWith(_ => 
				{									
					this.InvokeOnMainThread( () => 
					{			
						var uri = NSUrl.FromString(callbackUri);
						UIApplication.SharedApplication.OpenUrl(uri);
									
					});

				});

		return true;
		
	}
}

: LaunchServices: application launch failed – timeout waiting for launch.

This works like a charm :). First, we got rid off the launch service error (shown above). Second, App B is now returning the results to App A in less than 3 sec. If App B is in the background then it would return the data in less than 1 sec. Otherwise, it would take up to 3 sec to return the data. yayyy 🙂

A Journey of Hunting Memory Leaks in Xamarin

My client was reporting performance issues with an existing app that was developed internally, and I had to find the problems. So, here is my journey on finding the issues and resolving them. The resolution was a reduction of the memory usage to 1/4 of what it was and usage was stabilised to this level (1/4). I am hopeful that this blog post can help you too in refining your app and pro-actively resolving any performance issues.

Capturing Telemetry Data

The first step in optimisation must be setting your benchmark, and in order to do that, we need to know where we stand. Thus, I set up an integration with Azure Application Insights to capture all memory warnings, errors, warnings, and battery level monitoring. For details on integrating with Azure App Insights, you can read more in my previous post here. The relevant part for us in this post is capturing memory warnings. There are three ways to capture memory warnings in iOS as I listed them on StackOverflow, we will stick with AppDelegate, as this is applicable to both traditional Xamarin and Xamarin Forms.


public partial class AppDelegate
{
	...
	public override void ReceiveMemoryWarning (UIApplication application)
	{
		// this (MemoryWarningsHandler) is a helper that I created 
		// to capture more info when a memory warning is raised. Things like (nav Stack, running time, etc)
		MemoryWarningsHandler.Record ();
	}
}


Always, Always, listen to these memory warning notifications from the OS, even if you are not actioning them now

In Android, we could also do the same using Application.OnLowMemory (See Android docos) as below:


public class MyApp : Application
{
	...
	public void OnLowMemory ()
	{
		MemoryWarningsHandler.Record ();
	}
}

Once we received and captured these memory warnings on Azure App Insights, we will then know that we have a memory warning, and whoever is looking at the report will keep bugging you until you fix this problem, if the app was not crashing due to low memory 🙂

Investigating Low Memory Issues

Once we identified that there is a problem with Memory, we need to figure out where the problem is occuring. To do this, we could use Xamarin Profiler. At the time of this writing (March 2016), Xamarin Profiler is still in preview and has many known bugs, but it still provides a good starting point.
We can monitor a number of performance indicators using Xamarin Profiler including:

  • Memory Allocation
  • Dependency Cycles
  • CPU Time
  • Few more aspects of the app Performance

For this post, we are interested in memory leaks, so we can start a profiler session, by choosing Memory Allocation when the profiler starts. More info on starting a profiler session can be found on Xamarin website.

In previous versions of Xamarin Profiler, I was able to view the call tree which gave me a great view on where the issue exactly was. This was based on call stacks and it tells you exactly how much memory is used in every entity/method. Unfortunately, in this version, I could not get this to show me this detailed view, but I was able to capture few memory snapshots and monitor the growth of used memory. My diagram looked like this:

Memory Usage before optimisation

Memory Usage before optimisation

This made it very clear that we have a problem in our memory consumption, the memory usage was racking up to 600 MB in some scenarios. The important part was now finding where the problem is.

Identify Problematic Code

In the absence of the call tree view, I started using the app and monitoring the memory usage. I established that it was a particular Page (Xamarin Forms Page) that was causing the memory usage to grow rapidly. As you can see at the start of the application, things were quite alright. Then, I focused my attention to that page. Looking at the page, it seemed harmless. It’s only a screen-saver-like page for a kiosk app. I could see a couple of small problems, but these are minor and would not cause the memory to grow that quickly. The code of this screen saver page can be seen below:

    public class ScreenSaverPage : ContentPage
    {
        private readonly List<string> _imageSourceList;
        private readonly List<FileImageSource> _cacheImageSource = new List<FileImageSource>();
 
        private readonly Image _screenSaver;
        private int _currentImageIndex;
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();

        public ScreenSaverPage()
        {
            _imageSourceList = new List<string> { "Screensaver1.png", "Screensaver2.png", "Screensaver3.png", "Screensaver4.png" };
            
            // Caching it to Reduce loading from File all the time
            foreach (string fileName in _imageSourceList)
                _cacheImageSource.Add(new FileImageSource {File = fileName});

            _screenSaver = new Image
            {
                HorizontalOptions = LayoutOptions.FillAndExpand,
                VerticalOptions = LayoutOptions.FillAndExpand,
                Aspect = Aspect.AspectFill,
                Source = _cacheImageSource.FirstOrDefault()
            };
            var tapGestureRecognizer = new TapGestureRecognizer();
            tapGestureRecognizer.Tapped += async (s, e) =>
            {
                _cts.Cancel();
                await Task.Run(async () => await App.ResetInactivity(typeof (BaseViewModel)));
            };
            
            Content = _screenSaver;
            _screenSaver.GestureRecognizers.Add(tapGestureRecognizer);
            // Configure the OnAppearing to kick off the ScreenSaver
            Appearing += async (sender, args) =>
            {
                try
                {
                    await Task.Run(async () =>
                           {
                               while (true)
                               {
                                   if (_cts.IsCancellationRequested)
                                   {
					App.Logger.LogInfo("CANCELLED - In the Loop");
                                       break;
                                   }

                                   await Task.Delay(5000, _cts.Token).ContinueWith(async t =>
                                   {
                                       try
                                       {
                                           if (_cts.IsCancellationRequested)
                                           {
						App.Logger.LogInfo("CANCELLED - In the Action");
                                           }
                                           else
                                           {
                                               // this is the unnecessary Task
                                               await Task.Run(() =>
                                               {
                                                   _currentImageIndex = _currentImageIndex < _imageSourceList.Count 1 ? _currentImageIndex + 1 : 0;
                                                   Device.BeginInvokeOnMainThread(
                                                   () =>
                                                   {
                                                       _screenSaver.Source = _cacheImageSource[_currentImageIndex];
                                                    });
                                               });
                                           }
                                       }
                                       catch (Exception ex)
                                       {
					   App.Logger.Log(ex);
                                           throw;
                                       }
                                   }, _cts.Token);
                               }
                           });
                }
                catch (OperationCanceledException e)
                {
		    App.Logger.Log(e);
                    Device.BeginInvokeOnMainThread(async () =>
                    {
                        await Navigation.PopModalAsync();
                    });
                }
            };
        }
    }

Now, please do not ask me why it’s done this way, because this is just what I have been given from the existing app. The three problems that stood out to me were:

  1. Wiring OnAppearing event without unsubscribing.
  2. GestureRecogniser is added but not removed.
  3. A Task was being created every 5 sec unnecessarily.

However, these all were small compared to the main problem, and even removing all these together did not help in reducing the memory usage. so I switched off the part that swaps the screensaver images.


_screenSaver.Source = _cacheImageSource[_currentImageIndex];

At first, this looked harmless to me, and we were caching the FileImaeSource in a list, so we were not loading the images every time, we only loading them once and only swapping the source on the background image. However, it appeared that this was the root cause. Commenting this line out made the memory usage stay stable below the 200 MB mark, which was great news for me :).

Make sure that you have your benchmark before any optimisations, otherwise you would not know the impact of your changes.

Developing a Solution

To avoid swapping the image source, which by the way, I think it is a Xamarin Forms problem, but I will chase that separately, I started thinking of creating multiple static background images, and only toggle their visiblity. This meant that I would have 4 images loaded and all bound to fill the screen, but I only show (make visibile) one of them at a time. The Page code changed to be like this:


public class ScreenSaverPage : ContentPage
{
        private readonly List<string> _imageSourceList = new List<string> { "Screensaver1.png", "Screensaver2.png", "Screensaver3.png", "Screensaver4.png" };
        private readonly List<Image> _backgroundImages = new List<Image>();
	private  RelativeLayout _relativeLayout;
        private int _currentImageIndex;
        private readonly CancellationTokenSource _cts = new CancellationTokenSource();

        public ScreenSaverPage()
        {
            _relativeLayout = new RelativeLayout { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand };

		LoadImages (_relativeLayout);
		_backgroundImages [0].IsVisible = true;

         	var tapGestureRecognizer = new TapGestureRecognizer();
         	tapGestureRecognizer.Tapped += async (s, e) =>
            	{
                	_cts.Cancel();
                	await Task.Run(async () => await App.ResetInactivity(typeof (BaseViewModel)));
            	};
            
		Content = _relativeLayout;
		_relativeLayout.GestureRecognizers.Add(tapGestureRecognizer);
        }

	protected async override void OnAppearing ()
	{
		base.OnAppearing ();
		try
		{
			await Task.Run(async () =>
			{
				while (true)
				{
					if (_cts.IsCancellationRequested)
					{
						App.Logger.LogInfo("CANCELLED - In the Loop");
						break;
					}
					await Task.Delay(5000, _cts.Token).ContinueWith(async t =>
					{
						try
						{
							if (_cts.IsCancellationRequested)
							{
								App.Logger.LogInfo("CANCELLED - In the Action");
							}
							else
							{
								_currentImageIndex = (_currentImageIndex < _imageSourceList.Count -1) ? _currentImageIndex +1 : 0;
								Device.BeginInvokeOnMainThread(
								() =>
								{
									SetBackgroundVisibility(_currentImageIndex);
								});
							}
						}
						catch (Exception ex)
						{
							App.Logger.Log(ex);
							throw;
						}
					}, _cts.Token);
				}
			});
		}
		catch (OperationCanceledException e)
		{
			App.Logger.Log(e);
			Device.BeginInvokeOnMainThread(async () =>
			{
				await Navigation.PopModalAsync();
			});
		}
	}

	private  void LoadImages (RelativeLayout layout)
	{
		foreach (string fileName in _imageSourceList) 
		{
			var image = CreateImageView (new FileImageSource { File = fileName });
			layout.Children.Add (image, Constraint.Constant (0), Constraint.Constant (0), Constraint.RelativeToParent (parent => parent.Width), Constraint.RelativeToParent (parent => parent.Height));
			_backgroundImages.Add (image);
		}
	}

	void SetBackgroundVisibility (int currentImageIndex)
	{
		for (int i = 0; i < _backgroundImages.Count; i++) 
		{
			_backgroundImages [i].IsVisible = i == currentImageIndex;
		}
	}

	private static Image CreateImageView (FileImageSource source)
	{
		return new Image
		{
			HorizontalOptions = LayoutOptions.FillAndExpand,
			VerticalOptions = LayoutOptions.FillAndExpand,
			Aspect = Aspect.AspectFill,
			Source = source, 
			IsVisible = false
		};
	}
}

You would agree that this is a big improvement on what we had originally, and it shows clearly on the Xamarin Profiler when we run the app with this new change. The memory plot on the Xamarin profiler was looking like this:

Memory usage after optimisation

Memory usage after optimisation

This is a great reduction, and it is less than one third of what the app was using before (~ 600 MB), but I was still thinking that it needs to be optimised further.

Can We Do Better?

The graph above was showing me that the memory usage was still going up, not by much but still growing. Also, when I switch between screens/pages, I noticed that the screensaver page was taking lots of memory to start with (~ 50 MB), which is to create the images and FileSourceImage objects. However, I noticed that when we move away from this page (screen saver), these entities are not being cleared quickly enough by the GC. Thus, I added the following:


public partial class ScreenSaverPage : ContentPage
{
	...
	protected override void OnDisappearing ()
	{
		base.OnDisappearing ();

		PrepareForDispose ();
	}

	void PrepareForDispose ()
	{
		foreach (var image in _backgroundImages) 
		{
			image.Source = null;
		}

		_backgroundImages.Clear();
		_relativeLayout.GestureRecognizers.RemoveAt (0);
		_relativeLayout = null;
		_cts.Dispose ();
		Content = null;
	}
}

This helped dispose of the images and the gesture recogniser quickly enough and helped me keep the memory usage at around 130 – 160 Mb, which is a great result considering that we started with 600 MB. The other pleasing part is that memory usage was very stable and no major peak were found. It fluctuates slightly when you move between pages, which is perfectly normal but it goes back to a steady level around 130 – 160 MB.

I hope you find this useful and please do check your Xamarin apps before you release or whenever you get the time, as these things are hard to see but they could bite you when you go to prod 🙂

Any device, any platform, one Microsoft

Only a few years ago you’d have been hard pressed to have mentioned the following four words in a single blog post where you weren’t arguing for / against a way of doing things: Microsoft, iOS, Android and development.

Unless you’ve been living under a rock you will no doubt have seen Microsoft’s announcement on their intent to acquire Xamarin, a business very much about cross-platform application development.

For those of us working in this space this has really been a case of
“what took you so long?” rather than “why?”.

So why should you care? Let me explore this for you…

Please note I don’t have any more insight than you in what the acquisition means. However, based on Kloud’s experience building real business and consumer solutions using Xamarin, I’m going to give you what I think it means to those of us who develop platform-specific applications.

Some background

Microsoft has been working independently of Xamarin to produce its own toolchain for cross-platform application development for the past few years. You’ll note the majority of these are about enabling solutions on any platform which, again, is very different to Microsoft of years gone by.

Portable Class Libraries (PCLs)
A great enabler that unlocks transportable .Net code. These are a big part of the success of Xamarin as they have allowed popular .Net libraries to be made available for use off-Windows, even prior to Microsoft open sourcing the .Net Framework.
https://msdn.microsoft.com/library/gg597391(v=vs.100).aspx

Visual Studio Tools for Apache Cordova
Cordova is a great tool for facilitating rapid delivery of cross-platform applications where you are prepared to forgo some aspects of native capability. If you have a bunch of web-centric developers then the foundation components for Cordova will seem very familiar. The Visual Studio tooling is some of the best you’ll find and is actively maintained.
https://www.visualstudio.com/en-us/features/cordova-vs.aspx
Azure – Mobile Apps, Notification Hubs & Mobile Engagement
Probably the most mature mobile back-end platform about. Integration with APNS and GCM just works and the quick-starts are a great way to dip your toes into mobile application development. The addition of Capptain in 2014 (now Mobile Engagement) bolstered this offering.
https://azure.microsoft.com/en-us/services/app-service/mobile/

Windows Bridge for iOS (formerly Project Islandwood)
There’s no denying iOS and Android are leading platforms, so how do you allow existing applications to run on Windows? You use a Bridge.
https://dev.windows.com/en-us/bridges/ios
Windows Bridge for Android (formerly Project Astoria)
This one’s an interesting one. Unlike the iOS Bridge, Astoria isn’t moving ahead. What happens here? We’ll have to wait and see, though no doubt Xamarin plays a part.
http://www.windowscentral.com/microsoft-officially-cancels-project-astoria-bridge-porting-android-apps-windows-10-mobile

So, C# is the future?

If you’re an experienced iOS and Android developers using Objective-C, Swift or Java you don’t need to drop everything you’re doing and pick up C#.

Chances are you aren’t particularly interested in it… but… you are in an extremely good position to pick up and run with development in this space using Xamarin and C#. Also, you can always import those native libraries you are already using anyway if you find a gap (which is unlikely).

C#’s syntax should not hold a lot of surprises for many iOS and Android developers, and as you already know a lot about the UI constructs on each platform you’re ahead of the pack. While it’s true that a C# developer can quickly deliver solutions using Xamarin, the nearer you get to the UI experience the more platform-specific knowledge you require, even if you leverage something like Xamarin.Forms.

APIs ahoy!

Existing C# developers also get benefits here as they can quickly build cross-platform solutions and only leverage specific skills for certain aspects of the applications (typically the UI). Write it once, deploy on any platform (where have I heard that before???) really comes true here in many cases.

Many great apps are let down by terrible APIs, either through poor performance or security. Imagine a world where your API implementation experts can also write the client libraries that will consume those APIs? C# and Xamarin unlocks this scenario.

But I already have an app for X

When I spoke about Xamarin at TechEd Australia 2013 the number one question I got after the session was along the lines of “I already have an native app on X, why would I use Xamarin?”

This is a fair question and to suggest that you simply re-implement the application in C# with Xamarin is not the answer you want to hear.

No doubt, though, you are eyeing at least one other major mobile platform in the market and wondering how your existing application can reach that platform.

You have two choices: go native or go cross-platform.

This is your sweet spot – go cross-platform. Eventually you will find a smaller incremental change will deliver you the same cross-platform application on your existing platform of choice.

Yeah, but a native app’s so much better

In the smallest of circumstances you may be right. As I said, Kloud has successfully built and deployed heavily used enterprise and consumer applications that I would dare you to pick as having been developed using Xamarin.

Xamarin has spent a lot of time documenting real-world use of their technology that I’d recommend you go and digest.

But it’s Microsoft!

Yes it is.

The one that has the leading productivity apps on iOS and Android platforms, supports Docker, has its own OpenSSH port, open sourced the .Net Framework, its JavaScript engine and works in the open on GitHub.

Microsoft’s strength has always been its understanding of the developer and the tools they need to do their work. Now with Xamarin you get this benefit regardless of your platform of choice.

Happy Days! 🙂

Google Cloud Messaging using Azure Notification Hub

The Xamarin team have provided a very helpful tutorial to get started with setting up Android notifications – I suggest using this to get the basic implementation working, and ensure you’re using the GcmRegistrationIntentService version, and avoid using the depreciated GCM Client.

To get a complete end to end solution up and running there is a fair bit of additional information required.  Here’s a guide for using Microsoft Azure Notification Hub.

Set up Google Cloud Messaging service

Log into the Google Developer Console (https://console.developers.google.com/), and if you haven’t done so already create a project for your application.

Once created make a note of the Project ID as this will be used in your application code.  When the application starts it will send the Project ID to Google to exchange for a device token.  This unique token is what will be used to target each device with a notification.  Be sure to check for a new token each time the application starts as it is subject to change.

Next step is to enable the Google “Cloud Messaging for Android” and create an API key:

GCM

Click credentials and create a new “Server Key” and make a note of it for later.  We’ll need it for when we set up the Azure Notification Hub, and also to test sending a notification.  Whist here you may want to think about how you’ll set up your dev/test/prod implementations as it’s a good idea to keep these separate.

Google_API_key

* the key used here is for dev purposes only!

Set up the Azure notification hub

Next step is to set up the Microsoft Azure Notification Hub.  Log into the portal and create a new App Service > Service Bus > Notification Hub.  As soon as the service is running you can configure the Google Cloud Messaging settings by entering the API key created in the previous step into the GCM API Key field.

Google_API_Key

Set up the Android code

Before you begin, make sure you add the following to your packages.config file:

<package id="Xamarin.GooglePlayServices.Base" version="25.0.0.0" targetFramework="MonoAndroid50" />
<package id="Xamarin.GooglePlayServices.Gcm" version="25.0.0.0" targetFramework="MonoAndroid50" />

For my implementation the client wanted to pop up a message when the customer is using the application as well as adding a message to the notification status bar. At the point of receiving the message I create a pending intent to display a message when the customer opens the app (by clicking the status bar message), and display a message if the application is open when the message is received.

public override void OnMessageReceived (string from, Bundle data) {

 Log.Info(TAG, "GCM message received");
	
 if (from == Constants.SenderId) // make sure we sent the message

 {
		
   try
	
   {
			
    var messageId = data.GetString ("account");
 // message ID		
    var message = data.GetString ("msg");
 // message body

    if (CurrentApplicationState.appIsInForeground)
        GcmMessaging.DisplayNotificationInApp();					
	
    // create a pending intent to display to the customer at a later date

    CreateSystemNotification (message, messageId);

		
   }
		
   catch (System.Exception e)

   {

    Log.Debug (TAG, "Error displaying message: " + e);
   }

  }

}

When a message has been received the following code is used to create the pending intent, which will fire when the user selects the notification from the Android notification status bar. For this notification I have chosen to display a message that can be expanded when the user selects it. The other important point here is the messageId is used when displaying the notifications. This ensures a unique notification will be displayed for each account in the status bar. If a notification is delivered with the same ID, then it will replace the existing one.

private void CreateSystemNotification (string message, int messageId) {
  
  Notification.BigTextStyle textStyle = new Notification.BigTextStyle ();
  textStyle.BigText (message);

  var intent = new Intent (this, typeof(MainActivity));
  intent.AddFlags (ActivityFlags.SingleTop);
  intent.AddFlags (ActivityFlags.ClearTop);

  var pendingIntent = PendingIntent.GetActivity (this, 0, intent, PendingIntentFlags.UpdateCurrent);

  var notificationBuilder = new Notification.Builder (this)
   .SetSmallIcon (Resource.Drawable.app_notifications_status_bar)
   .SetContentTitle (ApplicationInfo.LoadLabel(PackageManager)) // app name
   .SetContentText (message)
   .SetAutoCancel (true)
   .SetContentIntent (pendingIntent)
   .SetLargeIcon (BitmapFactory.DecodeResource (Resources, Resource.Drawable.agl_launch_icon))
   .SetSound (RingtoneManager.GetDefaultUri (RingtoneType.Notification))
   .SetStyle (textStyle);

  _notificationManager = (NotificationManager)GetSystemService (Context.NotificationService);
  _notificationManager.Notify (messageId, notificationBuilder.Build ());
}

To keep track of whether the application is in the foreground I use the following:

public static class CurrentApplicationState

{

 private static bool _appIsInForeground;
	
 public static bool appIsInForeground
	
 { 
		
  get { return _appIsInForeground; } 
		
  set 
		
  { 
			
    _appIsInForeground = value; 
		
  } 
	
 }
}

And I call this from my base application:

protected override void OnPause () 
{
	
 base.OnPause ();
	
 CurrentApplicationState.appIsInForeground = false;

}


protected override void OnResume ()
 {
	
 base.OnResume ();
	
 CurrentApplicationState.appIsInForeground = true;


}

In order for a user to receive notifications on his/her Android device they’ll need to have Google Play installed. There is no way of avoiding this as we are using the Google Cloud Messaging service! This code can be used to detect if Google Play is installed and on the latest version:

public static bool IsGoogleServicesAvailable ()
{
	
 GoogleApiAvailability googleAPI = GoogleApiAvailability.Instance;
	
 int resultCode = googleAPI.IsGooglePlayServicesAvailable (Context);
	
 if (resultCode != ConnectionResult.Success) 
	
  {
		
   return false; // There is an issue with the Google Play version installed on the device
	
  }

	
 return true;
}

Using this implementation you’re relying on Google to provide the messaging. I choose not to inform the customer at this point as the message from Google is fairly blunt. As you can see below it mentions the application won’t run without updating Google play which is not strictly true, as it will run fine! Instead I pop up a message at the point in which they configure the notification service, which happens much deeper in the app than the main activity!
Google_error

Using the simulator

If, like me, you find it easier to use the Xamarin Android emulator for debugging you’ll need to install Google Play before you can test notifications on the simulator.  Download the Gapps package from the following website: http://www.teamandroid.com/gapps/. Simply drag the zip file into the emulator window (this works on a Mac, I’m not sure about Windows?) and follow the on screen prompts to install Google Play.

Log in with a Google account and you’re ready to test your notifications!

Testing the service

In order to make sure things are running as expected you can send a test notification.  There are a number of ways to do this but my preference is to use Postman (the Chrome extension) with the following settings:

POST /gcm/send HTTP/1.1
Host: gcm-http.googleapis.com
Authorization: key=[YOUR API KEY]
Content-Type: application/json
Cache-Control: no-cache

And the body of the POST request:

{ 
   "type": "android", 
   "data": { 
     "title": 
     "This is the title of the message", 
     "message": "You have been served, from the Google Cloud Messaging service.", 
     "account": 123456789 
    }, 
    "to" : "eD4ceBas2SN3:APA93THISchdsISsasdNOTqwe9asczAasd98EHsdREALasd0c+KEYv0kx50GZPsyc3ah6_eyvur-wvwVQe6Lfbv5ICijBfYOCkujQK271sK-RmxTe-Y_Aofx1RCe7yfnYgK7MEL7xgqY"
}

Image below for further clarity!

Postman_settings

Or if you prefer you can also log into Azure and send a notification from there. In order to send a message to a specific device you will need to set up a server side implementation and then target a device using the “Send to Tag” option.  As I only have 1 device activated I can choose Random Broadcast and it will send an alert to my test device.

Screen Shot 2015-11-08 at 20.43.21

Summary
Hopefully this will have provided a good taster on how to set up Google Cloud notifications on Android using Microsoft Azure notification hub. In order to target specific devices you’ll need to create a server side API to maintain a dataset of devices and associated tokens. Hopefully if time permits this will be the subject of a future post!

If you’re looking for more information, I found the following sites helpful when setting this up:
The Xamarin Android notification guide: https://developer.xamarin.com/guides/cross-platform/application_fundamentals/notifications/android/remote_notifications_in_android/
Google Cloud Messaging docs: https://developers.google.com/cloud-messaging/

Taking Advantage of The (iOS 9) Universal Links on Xamarin iOS apps

What is Scheme URI?

In the context of mobile apps, Scheme URIs are used for communicating between mobile apps. Mobile developers can register a unique URI for each app in the application manifest (info.plist). The operating system would then use that to launch your application once the user clicks on a link that matches your uri. For instance, I could have my-cool-app:// as my scheme uri. I could then generate links (should start with my-cool-app://) to send in my email to my app’s users and once clicked, my app will be launched. These have become standard and they are widely supported on iOS, Windows, and Android.

What is Universal Links?

Universal Links is a new feature that was introduced by Apple in iOS 9. The idea is instead of registering a scheme Uri, you could use your own website domain name (which is inherently unique) and associate this domain name with your mobile app. Once the user clicks on a http/https link that links to your domain name, iOS would then launch your mobile application instead of opening the link in Safari. More details about Universal Links could be found in in this WWDC session and Apple’s official documentation.

Why Do we need Universal Links?

If you have used Scheme URIs before to open your mobile apps, you would know the pain of trying to keep your links valid to open your app (when installed) and fallback to the web links when your app is not installed. You would also know this was not a simple task, and there was no guarantee that this would work exactly the way you want. Therefore, Apple has introduced Universal Links, which is great. Imagine how many times you get a URL link via email and you click it to end up in a web browser asking you for username and password. Most people do not remember their accounts (at least not for all accounts), or they want to see this content on the mobile app instead of Safari. This new feature (Universal Links) solves this problem.

How Can we Enable Universal Links?

To enable Universal Links, you need to follow the following steps:

1. Enable “Associated Domains” on your Application Id (in Apple Developer portal).

Enable Associated Domains in your App Identifier settings - Apple Dev Portal

Enable Associated Domains in your App Identifier settings – Apple Dev Portal

2. Create an apple-app-site-association file on your domain. This is just a text file that contains a JSON object to describe your universal links. You could associate multiple link paths with multiple apps. Notice that your app id needs to have your full app identifier (TeamName.Appid). I’ve shown a sample of the JSON content below:

    {
        “applinks”: {
            “apps”: [],
            “details”: [
                {
                    “appID”: “ABC-Team-Id.com.my.bundle.id“,
                    “paths”: [ “/”, “*” ]
                }
            ]
        }
    }

This file needs to be served over HTTPS and have no file extension – it must be named “apple-app-site-association”. Apple will try to retrieve this file from your domain before it launches your app for the first time. This is to verify the authenticity of your domain ownership before starting the app. If you are hosting this file on an Azure Web App, you might also need to add a static content mapping in your web.config.

The bottom line is you need to make sure that you can navigate to this file as https://your-domain.com/apple-app-site-association. There is also a small app that helps you verify your Apple association file, you could find it here. Do not worry about the last 2 errors that it displays concerning signing your file. I have my Universal Links work without signing the association file, but this web page is still good to verify other aspects of the association file.

3. Add the Universal Links Entitlement to your info.plist. This can be done very simply by navigating to your Entitlements.plist and add the new applinks as follows:

Applinks in Entitlments-plist file

Applinks in Entitlments-plist file

4. Regenerate your provisioning profiles. This is very important since we changed our app id entitlements. If you don’t do this you will get an error message when trying to build the app saying that you have entitlements that are not permitted by your provisioning profile.

5. OPTIONAL: Override ContinueUserActivity method in your app’s delegate to capture the URL link that the user clicked on. This is necessary when you want to take the user into the particular screen in your application. For instance, if the user clicked on a link to view a product on your website, you could capture the link in this method and once your app opens up, view the details of that product on your mobile app.

public override bool ContinueUserActivity (UIApplication application, 
     NSUserActivity userActivity, 
     UIApplicationRestorationHandler completionHandler)
{
	Console.WriteLine ("ContinueUserActivity method has been called...");
	// you can get the url that the user clicked on here.		
	return true;
}

Once all the above is done, you can build and deploy to your device. I have tested my implementation by creating a link to my associated domain and sent it via email to the device. When I click on the link, I get redirected to my app directly (without going through Safari).

Applinks in the mobile app - screenshot

Applinks in the mobile app – screenshot

Notice that Apple give the user the option to stay on my app, go directly the browser (upper right link) or go back to the email that launched my app. I really like this design because it keeps the user in charge. Also, there are few posts that suggest once the user taps on the link to go to the browser, Apple would then bypass your app for this link and take the user directly to the website in the future. I have not verified this but you could find the details on this Stackoverflow post.

How about devices that are still using older versions of iOS?

What we have seen above is very cool stuff and I have been hoping for this for years. However, this only solves the problem on a subset of devices. Remember there are still lots of devices out there that are not using iOS 9. If you are like me and are required to support iPhone 4, then you need to have a fallback mechanism for these devices. For this scenario, we could have simple JavaScript code that helps us redirect to our mobile app, if this redirection fails, then we assume that the app is not installed and we redirect the user to our web URL. A sample of this is below, and more details can be found on Stackoverflow:


// this could needs to sit in your website page
setTimeout(function() {
  window.location = "http://my-domain-app"; // or your could put  link to your app on iTunes
}, 25);

// If "my-cool-app://" is installed the app will launch immediately and the above
// timer won't fire. If it's not installed, you'll get an ugly "Cannot Open Page"
// dialogue prior to the App Store application launching
window.location = "my-cool-app://";

Future-Proofing

It will be very interesting to see how Apple will use this to integrate apps more with the web. Apple has already done a great work in terms of search and user activity that is bridging the gap between web and native apps. Universal Links is another step in the right direction.

How about Android?

Although most of the contents of this post is related to iOS, Android’s implementation is quite similar. Google introduced this in Android M and you can read more about it on the Android developer documentation site.

Solving self signed certificate blocking by inspecting web requests using Xamarin iOS

In iOS 9 Apple have turned on App Transport Security (ATS) as default. So if your iOS application is connecting to an insecure url resource then you’re out of luck as it will be blocked, an example of the most likely culprit is viewing a webpage without SSL encryption.

With the current application I’m working on I ran into trouble whilst loading a dev resource only to find it was using a self signed certificate and being blocked by the OS. I also had a requirement to inspect an Ajax web request and the WebView ShouldStartLoad delegate was not receiving these request callbacks.

First things first, if your applications requests are being blocked you will see something like:

NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802)

The best way to resolve this issue is to ensure all resources are securely protected in the correct way, and therefore your application, and users data, is secure!

But this is not always possible!  And if you’re like me then you have no choice but to step around the default ATS setting.

Quick, change the Info.plist!

To resolve a problem with a blocked resource you can turn off ATS for you application with a single entry in your Info.plist file. Whilst this is the simplest and quickest approach, my advice would be to avoid doing this. Yes, you may just be making the change for a quick test or prototype app, but it’s easy to forget you made the change and before you know it you’ve released an insecure app to your users.

My advice is to turn off ATS for the only resources you trust. In my case a single domain.

This can be achieved by adding the following into your Info.plist file:

<key>NSAppTransportSecurity</key>
	<dict>
		<key>NSExceptionDomains</key>
		<dict>
			<key>[ENTER YOUR BASE URL HERE]</key>
			<dict>
				<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
				<true/>
				<key>NSIncludesSubdomains</key>
				<true/>
				<key>NSAllowsArbitraryLoads</key>
				<true/>
			</dict>
		</dict>
	</dict>

Spying on all requests

iOS is no longer blocking my webpage but we need a way to listen in to all requests our web view is making so we can work our magic with trusting the self signed certificate (remember this part is for dev releases only and not production).

Start by creating a new class and have it inherit from NSUrlProtocol.  Then override the default delegate methods so that we can add our custom logic.

[Export ("canInitWithRequest:")]

public static bool canInitWithRequest (NSUrlRequest request)
{
   Console.WriteLine (String.Format ("URL # { 0}. Loading URL: { 1}", counter.ToString(), request.Url.ToString()));
   
   counter++;

   if (CustomNsUrlProtocol.GetProperty(MY_KEY, request) == myObj)
   {
      return false; // request has already been handled	
   }

   return true;
}

Here we get the opportunity to check all requests before they are loaded, and make a decision if we need to do something clever or not.  The default behaviour here is to return ‘true’ which means we need to do something.  So let’s do something…

public override void StartLoading ()
{
   // start loading the URL now we have handled it
   new NSUrlConnection (Request, new CustomNSUrlConnectionDataDelegate (this, new NSUrl(Constants.baseUrl)), true);
}

The clever part is to create a new instance of a NSUrlConnectionDataDelegate and use this delegate to inspect the certificate of each request.

Finally we just need to tell our custom protocol that we have now dealt with this request and we do not want to see it again.

public override NSUrlRequest Request
{
   get {
         NSMutableUrlRequest mutableRequest = (NSMutableUrlRequest)base.Request.MutableCopy ();
         CustomNsUrlProtocol.SetProperty (myObj, MY_KEY, mutableRequest);
         return mutableRequest;
   }
}

We’ve assigned an object to our request.  Now when it attempts to load, via canInitWithRequest, it will recognise that we have already dealt with this request and the browser will continue to load the request as normal.

On to the magic

So far you’ve probably noticed we haven’t actually done anything with our requests other than inspect them and assign an object to say we have done so.

Create a class that inherits from NSUrlConnectionDataDelegate and override CanAuthenticateAgainstProtectionSpace.  This method will be called if we receive an authentication for any of the requests we pass if from our NSUrlProtocol.

public override bool CanAuthenticateAgainstProtectionSpace (NSUrlConnection connection, NSUrlProtectionSpace protectionSpace)
{
   #if DEBUG || TEST
      if (protectionSpace.AuthenticationMethod.Equals (Foundation.NSUrlProtectionSpace.AuthenticationMethodServerTrust))
         return true;
      return false;
   #else
      return false;
   #endif
}

The default value we return is false which means we will not authenticate against any insecure connections.  However, if we receive a challenge and we are running in the development or test environment then we return true as this is something we want to handle.

Finally I use the delegate ReceivedAuthenticationChallenge to trust the request.

public override void ReceivedAuthenticationChallenge (NSUrlConnection connection, NSUrlAuthenticationChallenge challenge)
{
   var baseUrl = new NSUrl(Constants.baseUrl); // this is the base URL we trust

   // check we trust the host - an additional layer of security
   if (challenge.ProtectionSpace.Host.Equals (baseUrl.Host))
   {
      challenge.Sender.UseCredential (new NSUrlCredential (challenge.ProtectionSpace.ServerSecTrust), challenge);
   }
   else
   {
      Console.WriteLine ("Host not trusted: " + challenge.ProtectionSpace.Host);
   }
}

A quick check to ensure the URL is from a webpage I trust, and if so I provide my own credentials and reload the connection.  Re-run the application and if all goes well there will be a heap of URLs written to the debug log as they are ‘taken care of’ and the page will load as normal.

As always, leave a comment below if you have a question.  A sample project with the complete working code can be downloaded from here.

If you’re after more information or want to introduce more control over your request loading then I recommend this page as a starting point: https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html

Azure Applications Insights for Xamarin iOS

Azure Application Insights (AI) is a great instrumentation tool that can help you learn about how your application is doing during run-time. It is currently in Preview mode, so bear that in mind when developing production ready apps. It gives you the ability to log lots of different kinds of information like tracing, page views, custom events, metrics and more.

Azure AI supports multiple platforms, but unfortunately they have not released a Xamarin package yet. There is one library which is for Xamarin.Forms since it uses the DependencyResolver. I have taken that and removed that dependency to make it compatible with Xamarin.iOS. You could do the same thing to use it for Xamarin.Android too if you like.

It’s very simple to use, all you need is your instrumentationkey which you can get from your Azure portal. Follow the steps from the MSDN tutorial as you can see here to create the Azure AI instance and get your key. Once done, you could download and reference the repository that I have created on GitHub, as you can find it here.

To start Azure AI on your Xamarin iOS app, you could do:

    
	AzureAIManager.Setup();

	AzureAIManager.Configure("my-user-or-device-name");

	AzureAIManager.Start();

The implementation of the AzureAIManager is as follows:


	public static class AzureAIManager
	{
		public static void Setup(string appKey = "your-azure-AI-instrumentation-key")
		{
			AI.Xamarin.iOS.ApplicationInsights.Init();

			var ai = new AI.Xamarin.iOS.ApplicationInsights ();
			ApplicationInsights.Init (ai);

			TelemetryManager.Init(new AI.Xamarin.iOS.TelemetryManager());
			ApplicationInsights.Setup(appKey);

		}

		public static void Start()
		{
			ApplicationInsights.Start();
		}

		public static void Configure(string userId = "" )
		{
			ApplicationInsights.SetAutoPageViewTrackingDisabled(true);

			if (string.IsNullOrEmpty(userId))
				ApplicationInsights.SetUserId(userId);
		}

		public static void RenewSession()
		{
			ApplicationInsights.StartNewSession();
		}
	}

I have not put this as a Nuget package because I am sure Microsoft will release one very soon, so until that happens, you can use this bindings to play around with Azure AI and you could even use it on your small projects.