0 Comments

pexels-photo-297755

If you have ever written a Xamarin Forms app and wanted to navigate from within a View Model to another page. Then you have come over the issue that the navigation logic usually resides in the view. Since every best practice blog post, course and video tells us that the view and business/control logic should be separate. We are often left with the question how to integrate a View Model based navigation.

What we want to do

The goal of this post is to show you how we can initiate a navigation call from the View Model. Without adding dependencies to your view or writing call back methods.

Navigation 101

In Xamarin Forms there are two fundamental ways of navigating between pages:

  • Push
  • Modal

Push navigation is the most straight forward way for navigating in an app. The main page in the App.xaml.cs is a NavigationPage which contains the main page displayed to the user:

When navigating to the next page, the page gets pushed onto the navigation stack. The user can then navigate back via Screen (iOS & Windows) or Hardware button (Android & Windows). Navigating back will dispose the current page, pop a page from the navigation stack and display it to the user.

When navigating to a page using Modal. The target page is displayed in a separate navigation context. This results in the behaviour that the user is no longer displayed with a software back button from the OS. The back navigation call differs from Push. Thus it requires invoking a different method of the Navigation Page.

Modal navigation is a great option to capture the user on a view. This is not generally what we intend to do with a user. But if the user has to login or the users consent is required (are you really sure...) filling out a form. Then modal navigation allows keeping the user on a page and handling the navigation via custom defined logic.

Note: Modal navigation is an iOS concept in it’s origins. Under Android and Windows the user has system buttons to navigate the app. If the user should not be able to leave the page and return to the previous page I.e. user has to login first. The developer will have to override the OnBackButtonPressed with a return true in the code behind of the view.

Navigation TL;DR;

We have two navigation methods in Xamarin.Forms. These are Push and Modal. Each has different ways of invoking the navigation. Which also applies to the back navigation.

Using a navigation service

In general the navigation service will have to contain a Navigation Page to handle the navigation stack. Further it needs to offer a Method for navigating to a page via push or modal navigation and allow navigating back.

The initialisation of the navigation service can now be done in the App.xaml.cs by registering all the views with a corresponding key.

In a view model we can now navigate to a page by providing the service with the key of the target page. If required we can also pass in a parameter. Since the parameter is of type object there are no limitations there.

As mentioned before modal navigation leaves the current navigation stack and displays the page on it’s own. If we want to navigate from a modal root page via push to a child page. The modal root page has to be in a Navigation Page itself. This is what the navigation service does automatically. It further removes the navigation header of the modal root page.

Back navigation checks what back navigation is intended for the current page. A root page in a navigation stack is either the root page of the app or a root page in a modal navigation stack. In either case it will choose the appropriate back navigation method.
If the page is not the root page we simple navigate back to the previous page that was pushed onto the navigation stack.

Conclusion

Using the navigation service described in this blog post. It is possible to navigate from the view model to other pages. Doing so we do not add dependencies to the view stack e.g. Xamarin Forms. Nor do we have to write cumbersome call back methods for each navigation action over and over again.

I would like to thank Laurent Bugnion at this point who laid down the base of the described navigation service above in with his initial implementation of a Navigation Service for Xamarin Forms when using MVVM Light.

You can find a running sample on GitHub.

0 Comments

Xamarin Test Cloud Logo

Automatically testing apps is not only a huge time saver but it also ensures that bugs introduced into the system get quickly caught. This leads to a shorter timespan to fixing these bugs since the memory of what has changed is still fresh in the head of the developers so overall shorter time means less money spent on hunting down bugs and more time to implement the next juicy feature. When developing a Xamarin application one can choose to run the Unit- and Integration Tests on a device/simulator to get a feeling how the logic will behave and perform in the real world. But with Xamarin Test Cloud we can go one step further and test the UI i.e. the entire stack of the application automatically. If you are interested into a general introduction into the topic I recommend you read this post before diving into the technical details of the lines to follow.

For writing a Xamarin Test Cloud (XTC) test the Xamarin Toolchain has to be installed. This post was written using Visual Studio 2015 Update 2.

Having a look at the app

Since this post focuses on writing UI tests the app is rather simple but will show the basic steps required to write maintainable UI tests. The app under test is a basic app with an input field, a button and a button that displays the entry of the input field. The app is based on the MVVM pattern (using MVVM Light) and is based on Xamarin.Forms.

Screenshot of app that is going to be tested.

When a user enters a message and submits it, it will appear on the label bellow. Now that the basic outline is defined, lets have a look at how we can implement a UI test for the app.

Writing UI Tests

If you created your Xamarin.Android and iOS projects with UI tests from the beginning you can skip the next steps and just start writing the tests. If not do not despair a few easy steps will allow you start writing those UI tests in no-time.

Setup

To start writing UI tests we first have to add a UI testing project to an existing project. Simply selecting the UI Test Project will create the Project in the solution. What is still left to do is associate the Project we want to test with the test project. Right click onto References, select the Android and/or iOS Project you want to test and simply add them:

Adding iOS And Android App Projects to a UITestProject

If you take the default UI testing project from Visual Studio you might want to check if you have the latest version for Xamarin Test Cloud. Update XTC to 1.1.0 or higher or else you will get an error when executing the tests which is asking for an API key.

Starting with Xamarin Test Cloud 1.1.0 or higher you no longer need a subscription for Xamarin Test Cloud to execute the tests locally.

iOS and XTC

To run UI tests on iOS there is an additional library required that is included in the app - only the debug version, this will not be deployed to the store. Add the Xamarin Test Cloud Agent package to your iOS Project, then edit the App Delegate to look the following:

Next open the Properties of your iOS project and ensure that Debug build configuration under the Build tab defines the Symbol: ENABLE_TEST_CLOUD

iOSProjectConfiguration

Now this symbol must only be set for Debug builds. Trying to submit an app with the calabash package included will lead to a rejection when trying to submit the app to the store.

Writing tests

Enough chit chat, lets start writing those tests already. In the UI test project the Tests.cs class file contains the basic setup for a test. Lets change the AppLaunches method to this:

Now when we start the test for i.e. Android the App will be started and a Read Eval Print-Loop (Repl) console will open. One of the most used commands when using the Repl is treenow if we execute the command the following output will be printed:

Shows the XTC Repl tree command when a UI has no Ids set.

Now we can identify some of the controls, but it would be a lot better if we could just identify the elements over Ids. So lets just do that. Lets start by adding an AutomationId to all of our controls:

Next we will have to add a couple of lines of code to the AppDelegate.cs in the iOS Project:

And the MainActivity.cs of the Android project:

If we rerun the test again and execute the command tree we will now see the following output:

XTC Repl showing Ids after executing the tree command

Working against Ids is considered best practice. For instance if the app is required to be available in multiple languages the UI test will work when the device is set to a different locale and can be used to acquire screenshots

In the Repl, we can now type in the following commands which will write a text in the Entry control, then submit the message and read out the text value of the label displaying the last submitted message:

Repl with the entered commands.

One can use the copy Repl command to copy all of the executed commands to the clipboard (the tree command will be discarded from copying). We can create a new test method and simply paste the copied commands from the Repl. Add an Assert for the Text input et voila, we have created our first basic UI test. Smile

Now the test has been added with some additional lines that capture a screenshot of the app. These screenshots can be of great value when not observing the test while it is running. And since automation is all about freeing up the human to do other tasks you should enable your tests to take a screen shot after any meaning full step.

Please note that taking screenshots does increase the runtime of your tests slightly so you might want to enable a global constant which allows you to easily en- i.e. disable the screenshots.

Further when running your tests on the Xamarin Test Cloud the screen shot will allow you to get a lot more information about each step such as CPU & RAM usage at the time of the screenshot. So it also allows you to get more telemetry of the app when the screenshot is taken. The string you pass to the method will also appear as under the test.

Executing Tests

After creating the test we can run it on either Android or iOS. Per default the IDE settings are taken for executing the test so it is possible to select different emulators e.g. in Visual Studio you can select different Android Emulators to execute the tests on. If one hooks a device to the computer it is even possible to execute the test on the device. Again for all this there are no licenses required. The tests are base on NUnit, so as long as a NUnit Testrunner is installed the tests should just simply execute.

Showing test run result with the app in the background. The resharper NUnit Testrunner was used to perform the testrun.

At the time of writing this blog post the iOS execution is only possible on a Mac.

A small side note regarding the execution time of the test. Due to the fact that the app has to be deployed and then executed on the device the test takes a couple of seconds to run through. If we would think about an Integration Test performing the same task we would have a much shorter runtime, but would not be able to see if the information is correctly displayed on the screen for the user. Just keep in mind that UI Tests in general take a while longer to perform the same test that a integration test would need and that it is worth to choose beforehand which tests to execute.

Running in the cloud

As stated before it is possible to execute the tests locally. This could even be integrated into an automated build process. But there are some limitations when executing the tests locally. For instance if we decide to attach a device we have to maintain that device. Ever heard of bloated batteries, broken cables and the like? Well those things can/will happen, further it is not possible to parallelise the tests locally out of the box. Another aspect is easily adding devices to the test set, well all this is what is the great strength of running your tests on Xamarin Test Cloud. Running the tests on the Xamarin Test Cloud can easily be integrated into a build server and allows to easily run the app on multiple devices (in parallel) and even allows to parallelize the execution of tests on multiple devices of the same type. So in short Xamarin Test Cloud offers a wide collection of devices with different OS versions that do not have to maintained and choosing which devices to use during the tests can be easily configured and changed. The results are displayed on a dashboard:

Screenshot showing the dashboard of XTC results for a testrun.

There is even an API that allows to control the execution and collect the results of a test run.

Currently there are still some details missing from being available for the extraction. Such as the snapshots taking during a test run. If you would like the team to add this or other features please feel free to rate it up or tell them here.

Conclusion

In this blog post we saw how a UI Test based on Xamarin Test Cloud is created. How the UI for Xamarin.Forms should be adapted to make writing of UI tests more robust. Further we saw how we can configure the tests to capture screenshots from steps performed during a test run. Capturing screenshots of a test run not only allows to see more easily where a functional error occurred but also allows to see how the screen looks for a given device and if the layout is behaving as expected.

You can find the sample project and the test code on GitHub.

HTH

Further Reading

Getting started with iOS.

0 Comments

Blog Title Image showing ios logo and Beta Testing with a ruber stamp effect.

When developing your latest and greatest (Xamarin) iOS app there will come a time when you are ready to ship the app to users for some beta testing. This allows you to get some feedback before shipping it to the official store. First thing needed is the application package also known by it’s file ending the IPA. If you are using Xamarin.iOS you can find a more details on building the IPA and setting up the certificates here. Assuming that you have an IPA ready for distribution the most common instruction found on the internet is to use iTunes to side load the app. Now this has a bit of an indirection to it, since the user must be sitting in front of a Laptop which allows him to install the app. In case of a company Laptop with IT policies this may end up being rather complicated. But there is an easier way, you can send a link which the user can select on an iOS Device which will install the app directly onto the device.

For the user to be able to use the app the certificates have to be correctly configured. If not, the user will be able to install the app but unable to launch it, which shows itself with by either closing right after the splash screen or a greyed out app icon.

Sharing your app via link

Now since it would be way to easy to just simply send a link to a file share which allows you to install the app, we jump through an additional hoop to comply with Apples “process”. We need to send the user(s) a link to a plist file that includes a link to the actual app i.e. IPA file:

Now lets go through this step by step:

  1. Upload IPA to the file share of your choosing and get a public URL for the IPA
  2. Edit the plist template above to match the requirements of your app (note the comments)
  3. Upload the plist file to Fileshare and get a public URL to the plist-File
  4. Send link to plist-File to whomever you would like to have the app installed

Since I was met with a confused look the first time I explained this to a co-worker see the graphic bellow and just think of the link to the plist file as a pointer of a pointer Winking smile:

Shows image where beta users taps on a link that is pointed towards the plist file (lying on a file share). The plist itself contains a link to the ipa file which will get installed on the users device.

This is a super easy way to share your app with testers. Then again these steps have to be performed for each update of the software and there is no user monitoring included with this approach. So you can not see if the app crashed nor can you know if a user already installed the latest version of the app. Or simply inform the user while he is using the app that there is an update. Now all this can be included in an app but it requires quite some effort to do so and then again we are talking about code that is only used during beta testing. So if you are developing a larger app with a longer lifetime or multiple beta releases you might want to consider a third party service e.g. Hockey App.

Conclusion

Setting yourself or your company up for running beta tests for iOS is as easy as sharing a link to a file (with some overhead for the publisher). No additional accounts needed or third party services. You could even share this thing from a NAS. That being said I would recommend you check out Hockey App as they do provide a free tier for up to two apps for free (at time of writing) and the process of adding it to your app is a couple of lines of code and a NuGet package.

HTH

0 Comments

nuget

See how you can easily create NuGet packages to publish cross platform C# libraries that allow to integrate platform specific code in your Portable Class Library (PCL) based Projects. In a former post you can read about how to create a cross platform library and see how the library has to be consumed by the e.g. app consuming the library. This post builds up on where that last post left off and shows how we can use the library providing the OS version number in a NuGet package. So the package we want to create has the following structure:

 

  • OSVersion.Core
  • OSVersion.UWP
  • OSVersion.Droid
  • OSVersion.iOS

 

Our goal is to generate a single NuGet package which can be added to any of the above named platforms.

Note: Though this post focuses on the platforms Universal Windows Platform (UWP), Android and iOS the approach can be easily extended to support additional platforms such as .Net, Silverlight et al.

Creating the package definition

First of all we will need to install the NuGet command line tool. Make sure that you add it to your PATH. After it is added to your path you can execute the NuGet commands with PowerShell. To create a NuGet package you need a nuspec file which you can generate by executing the command):

nuget spec

The location of the nuspec file does not really matter – I tend to have it in my root directory i.e. where the Solution file is. If you open the file in your lightweight editor of choice, you can edit the package specification to your gusto or for our sample somewhat like this:

<?xml version="1.0"?>
<package >
  <metadata>
    <id>OSVersion</id>
    <version>1.0.0.3</version>
    <title>OS Version</title>
    <authors>Mark Allibone</authors>
    <owners>Mark Allibone</owners>
    <!--<licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>-->
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Get the OS version for your UWP, Android or iOS app.</description>
    <releaseNotes>This is the initial release.</releaseNotes>
    <copyright>Copyright 2015</copyright>
    <tags>OSVersion</tags>
  </metadata>
  
  <files>
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.dll" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.pdb" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI\bin\Release\OsVersionAPI.Core.xml" target="lib\portable-net45+wp8+wpa81+netcore45+monoandroid1+xamarin.ios10+UAP10\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.dll" target="lib\UAP10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.pdb" target="lib\UAP10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.UWP\bin\Release\OsVersionAPI.Core.xml" target="lib\UAP10\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.dll" target="lib\monoandroid1\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.pdb" target="lib\monoandroid1\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.Droid\bin\Release\OsVersionAPI.Core.xml" target="lib\monoandroid1\OsVersionAPI.Core.xml" />
    
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.dll" target="lib\xamarin.ios10\OsVersionAPI.Core.dll" />
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.pdb" target="lib\xamarin.ios10\OsVersionAPI.Core.pdb" />
    <file src="OSVersionAPI.iOS\bin\iPhone\Release\OsVersionAPI.Core.xml" target="lib\xamarin.ios10\OsVersionAPI.Core.xml" />
  </files>
</package>

Beware of the target folder structure, these names may seem a bit strange (I’m looking at you Xamarin.Android…) but these actually have to align with a pattern or else you will run into problems when installing the NuGet package. You can find the target folder names on the NuGet website.

Integrating some Metadata in the NuGet package

You are not required to add the pdb (used for Debugging) or the XML file (Code Documentation for Intellisense) but it is considered best practice and makes the life of the developer using the library easier so I would suggest you follow along with this.

To enable the XML metadata file, right click on a project under Properties, Build you can set the checkmark for XML documentation file. Now you should have an XML file in your build output.

Per default the pdb file should be generated during the build, except for iOS (it’s always you iOS isn’t it…) - anyhow, right click on your project then under Properties, Build, Advanced… set Debug Info to pdb-only.

Beware that these settings are per build Configuration so make sure you set it for Release builds as you usually ship the Release build of a library.

Packing it up

Now all that is left to do is creating the package which we can do with the following command:

nuget pack

After the package is created the next thing to do is make it available for consumption. This means either pushing the package to NuGet or creating your own NuGet repository. Due to the fact, that this here is only a demo I will go with the second option.

Integrating the package in an app

Now we can simply add the OS Version library over the package manager. Notice that we get the same result as in the former blog post but this time the developer using the library will not be required to add the library multiple times to the project i.e. this potential error source no longer exists.

So when we now run the app under UWP we get the following output.

Win10VersionNumber

Note if we would only add the NuGet package to the NativePcl.Core project the output would simply show the stub implementation.

StubVersionNumber

So all the principals that were described in the last post still apply. But adding the library has been greatly simplified.

Conclusion

In this blog post you saw how a cross platform NuGet package can be created which lends itself very well to create cross platform libraries that implement native features which have to implemented differently for each targeted platform. There are many great libraries already out in the wild that use this approach e.g. MVVM Light, SQLite, PCL Storage and many many more.

You can find the sample project on GitHub.

2 Comments

3856456237_f05ebd2602_o

The Portable Class Library (PCL) allows developers to share C#, F# and VB code across multiple devices, platforms and runtime environments such as .Net, Xamarin or Windows Store Apps. In this previous post you can see how you can write portable business logic and integrate it with all the various platforms. But what if you actually want to use something the other way round say the GPS position, file system etc.. What then? This is exactly his post we will look at the following topics:

  • Using Interface Segregation and Dependency Inversion to our favor
    • Interface in the PCL
    • Implementation on the Platform
  • Injecting the implementation at runtime into the PCL
  • Making the resolution of dependencies a breeze with MVVM Light

So lets get to it!

Using Dependency Injection to our favor

Remember SOLID? Well it turns out the last letter stand exactly for the pattern we will be using to solve our “How will I be able to use a platform specific feature cross platform “. The PCL code is platform independent and therefore can be used across multiple platforms, so we want to put near to all of our business logic into a PCL. Further by accessing concrete class implementations via interfaces we can define an Interface in the PCL and create it’s concrete implementation in a platform specific project.

PCLDIOverview

Dependency Injection in action

For example lets say we want to display the current OS version for each platform, this is a very platform specific feature. To access such a information in the PLC we first define an Interface in the PCL that describes the contract the implementation has to implement:

public interface ISystemInformationHandler
{
    string OSVersion { get; }
}

In the concrete platforms we can then inherit the interface and implement the handler which calls the platform specific API (bellow you see the Android implementation):

internal class SystemInformationHandler:ISystemInformationHandler
{
    #region Implementation of ISystemInformationHandler

    //public string OSVersion => System.Environment.OSVersion.ToString();
    public string OSVersion => $"Android {Android.OS.Build.VERSION.SdkInt} {Android.OS.Build.VERSION.Release}";

    #endregion
}

Now in the PCL we can have a class for example a view model that requires the handler to display the information.

public class MainViewModel : ViewModelBase
{
    private readonly ISystemInformationHandler _systemInformationHandler;

    public MainViewModel(ISystemInformationHandler systemInformationHandler)
    {
        if (systemInformationHandler == null) throw new ArgumentNullException(nameof(systemInformationHandler));
        _systemInformationHandler = systemInformationHandler;
    }

    public string OSVersion => _systemInformationHandler.OSVersion;
}

The view model requires as a parameter argument an instance of the IOSVersionHandler interface. So when we create an instance of the MainViewModel in the platform project, we can simply create an instance of interface and pass it into the view model when we create it.

var mainViewModel = new MainViewModel(new SystemInformationHandler());

And receive the following output for e.g. Android:

 

Cross platform Dependency resolution with MVVM Lights

Now resolving all of these dependencies by hand can get very tedious over time. You might have noticed that I’m using MVVM Light which comes with a lightweight Dependency Injection Container called Simple IoC. Lets see how we can use this component to further streamline our cross platform development efforts.

Note:for an introduction to MVVM Light please refer to this blog post for AndroidoriOSto get you started with the basics.

In the PCL we have the ViewModelLocator.cs which defines all of the instances used, but without the platform specific resolution.

public class ViewModelLocator
{
    public ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);

        if (ViewModelBase.IsInDesignModeStatic)
        {
            // Create design time view services and models
            SimpleIoc.Default.Register<ISystemInformationHandler, SystemInformationHandlerStub>();
        }

        SimpleIoc.Default.Register<MainViewModel>();
    }

    public MainViewModel Main
    {
        get
        {
            return ServiceLocator.Current.GetInstance<MainViewModel>();
        }
    }
}

On each platform we now extend the Locator and register the platform specific classes i.e. resolution for interfaces.

internal class Locator : ViewModelLocator
{
    private static readonly Lazy<Locator> _locator = new Lazy<Locator>(() => new Locator(), LazyThreadSafetyMode.PublicationOnly);
    public static Locator Instance => _locator.Value;

    private Locator()
    {
        SimpleIoc.Default.Register<ISystemInformationHandler, SystemInformationHandler>();
    }
}

Now we can simply request an instance of the view model (MVVM Light per default only creates one instance for each registered class) and use it. In Android this would look something like this in the MainActivity.cs:

[Activity(Label = "PclDISample.Droid", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : Activity
{
    #region UI Controls

    private TextView OSVersion => FindViewById<TextView>(Resource.Id.OSVersion);

    #endregion

    private MainViewModel VM => Locator.Instance.Main;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);

        // Get our button from the layout resource,
        // and attach an event to it
        OSVersion.Text = VM.OSVersion;

        var mainViewModel = new MainViewModel(new SystemInformationHandler());
    }
}

In Windows 10 we can simply set the Datacontext accordingly in XAML:

<Page
    x:Class="PclDISample.UWP.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:PclDISample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  DataContext="{Binding Source={StaticResource Locator}, Path=Main}"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <TextBlock Text="{Binding OSVersion}" VerticalAlignment="Center" HorizontalAlignment="Center" Style="{StaticResource TitleTextBlockStyle}"></TextBlock>
    </Grid>
</Page>

As you can see once all is registered with the simple Inversion of Control Container (IoC) of MVVM Light all of the dependency resolution will be performed automatically. If a dependency is missing, an exception will be thrown at runtime (not during compilation), so make sure to test all your views, user controls et al that they load correctly.

Conclusion

In this post you saw how you can use Dependency Injection to provide platform specific features to cross platform code located in the PCL without creating any circular dependency errors. By using interfaces in the PCL and injecting the concrete implementations during runtime we can create thin wrappers that provide platform specific features through a generic defined interface. Finally we saw how we can use MVVM Light to create a more manageable and more manageable dependency resolution with the Simple IoC Locator.

You can find the complete sample on GitHub.

Big thanks to Laurent Bugnion the creator the MVVM Light.