0 Comments

TitleImage

Writing Unit, Component and Integration tests allows to test functionality of software modules. In other words letting developers sleep tightly without worries at night. These tests run against certain parts of the code verifying the logic and interaction between modules of the app. All this is usually performed on the developers machine powered by a beefy processor and often unheard amount of RAM when it comes to mobile devices. Wouldn’t it be great if we could get a bit closer to the real thing? Well we can…

In this blog post we will look at how we can run xUnit.net tests on a device. The app will be a Xamarin(.Forms) app, which consists of three platform projects and a shared Portable Class Library which can be used to write logic that can be consumed on every platform.

Setting up xUnit.net

The typical xUnit.net tests are created in a standard .Net library. All that is required is the xUnit.net NuGet package:

PM> Install-Package xunit -Version 2.0.0

Now we can create start writing unit tests, for this blog post let’s stick to the basic calculator example in the BasicMathServiceTest.cs:

public class BasicMathServiceTest
{
    private BasicMathService _basicMathService;

    public BasicMathServiceTest()
    {
        _basicMathService = new BasicMathService();
    }

    [Fact]
    public void Add_GivenTwoNumbers_TheSumIsReturned()
    {
        var x = 35;
        var y = 7;
        var expectedResult = 42;

        var result = _basicMathService.Add(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Subtract_GivenTwoNumbers_TheSubtractedResultIsReturned()
    {
        var x = 456;
        var y = 123;
        var expectedResult = 333;

        var result = _basicMathService.Subtract(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Mulitply_GivenTwoNumbers_TheResultIsReturned()
    {
        var x = 2;
        var y = 2;
        var expectedResult = 4;

        var result = _basicMathService.Multiply(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void Divide_GivenTwoNumbers_TheSumIsReturned()
    {
        var x = 848;
        var y = 8;
        var expectedResult = 106;

        var result = _basicMathService.Divide(x, y);

        Assert.Equal(expectedResult, result);
    }

    [Fact]
    public void TheFailingTest()
    {
        var x = 4;
        var y = 2;
        var expectedResult = 8;

        var result = _basicMathService.Add(x, y);

        Assert.Equal(expectedResult, result);
    }
}

The code that we test against lives in a PCL and performs the calculations. Now let’s take these existing tests and execute them on the simulator or even a real device.

Running Tests on devices

For this first add the platforms on which the project will run. Now add the following xUnit.net NuGet package:

PM> Install-Package xunit.runner.devices -Version 1.0.0

Written by Oren Novotny whom we have to thank for enabling xUnit.net on Android, iOS and Windows Phone! This package will automatically add the xUnit.net and other dependencies required for running tests on your devices according to the platform to which it’s being added. Depending on the platform the xUnit.net for Devices package adds different template files as text files:

  • Android
    • MainActivity.cs.txt
  • iOS
    • AppDelegate.cs.txt
  • Windows Phone
    • MainPage.xaml.txt
    • MainPage.xaml.cs.txt

Simply replace the content of their default counterparts e.g. for iOS replace the AppDelegate.cs with the content of the App.Delegate.cs.txt (and thanks to some extra effort by Oren Novotny even the namespaces will just simply match Smile). Now you could simply start adding new class files and write out tests. The runner will automatically find them via reflection (even if you place them in subfolders).

Using existing tests

What is probably a more useful approach is to simply reuse existing tests. This is why in a next step lets see how we can add the unit test file BasicMathServiceTest.cs without creating a duplicate dopy. Simply right click on the Project then Add/Existing Item… browse to the unit test file and add it as link.

Shows the dropdown on the Add button that can be used to add a file as a link.

As a link to the file is simply a pointer to the original we only have to maintain one unit test file and all the links will automatically “update” as they simply reference the original.

Now the Project can be set as startup project and executed on the device. Bellow you see some sample screenshots from an iOS Emulator.

TestOverview

You can even dig into the error messages and see what went wrong during a test.

TestDetails

Conclusion

In this post we saw how to create and reuse xUnit.net tests on devices for iOS, Android and Windows. This can be very powerful when we have to test certain features on a device for example does this work with AOT on iOS? Or simply running integration tests on a real device, giving valuable insights and further allowing to tests performance, latency and so on.

This post focuses on xUnit.net and also shows one of it’s many strengths on the capabilities that can be easily added. The same can be done with NUnit which may be your testing framework of choice and which Xamarin provides project templates to run the tests on a device.

You can find the sample code on GitHub.

0 Comments

Xamarin Platform

Xamarin founded in 2011 (former Mono) has been enabling C# developers to write mobile apps for Android and iOS. Xamarin provides full access to the entire SDKs of the targeted platforms and therefore allows to build native apps that perform like apps written in the platform default language e.g. Java, Swift or Objective-C, look like native apps and provide a user experience like native apps. This makes it an ideal candidate to write high quality apps which provide a great user experience without having to rewrite the entire application for each targeted platform. See Christoph Rehmann’s post on an overview of Xamarin and a comparison to Hybrid and web applications in general.

Anatomy of a Xamarin application

The standard approach for writing Xamarin applications is to write The common approach of writing Xamarin apps allows to share all the platform independent code.

XamarinStack

But as soon as it comes down to writing the UI for the application or integrating native features such as a Widget or Push Notifications the developer will integrate those using the platform specific SDKs which usually are different for each platform. This is a logical coincidence for getting the full native SDKs and therefore also means that developers must embrace the platform designs and principals or else frustrated users will follow. For certain apps this approach makes a lot of sense as it allows to share the logic and present the user a native user interface that acts the way she knows and is accustomed to. Plus it let’s you design those fancy and unique UIs that really can set you apart from the competition. But what about the following two examples?

  • But in many apps there are screens that look pretty much the same across multiple platforms, this can be ranging from an about page, manual, checkout or login screen. With the standard Xamarin approach these views have to be written for each platform, though one might argue that apart from some small tweaks the UI stays greatly the same.
  • Other apps just want to allow the user aka employee to get stuff done while he is on the go. These apps are often form based applications that have the demand of getting out of the users way, work offline and be available on different form factors and in case of a Bring Your Own Device (BYOD) policy platforms.

For these kind of cases a lot of people start looking towards a HTML based or hybrid approach. Making a decision between native i.e. Xamarin and Hybrid is a discussion on it’s own. The gist is that Hybrid applications in theory allow you to not only share your business logic but also your UI, on the UI part you might end up writing code specific for each platform but as stated this shall not be the focus of this post. That being said wouldn’t it be great if for simple UIs we had the possibility to share the UI code across platforms? And this is exactly where Xamarin.Forms comes in.

Meet Xamarin.Forms

Given the requirements stated above, paired with the desire of relying on native applications with native user controls that not only looks like a native app but also performs the way the user expects an app to work is exactly the reason why Xamarin.Forms was created. Xamarin.Forms allows you to write your UI once and share it across multiple platforms resulting in a maximum of code being shared:

Xamarin.Forms

The UI is still fully native and allows the developer to create a native app experience. But instead of writing the UI over and over for each platform the UI is only created once and is then matched to the native controls and layouts that exist on Android, iOS and Windows (Phone). And the best part is that one can mix it with the standard Xamarin approach. So even if one is going for a unique design experience the simpler screens can still be written in Xamarin.Forms and shared across the platforms.

The UI

The UI is usually written in the Portable Class Library (PCL) which is a special library that allows code to be shared across C# library stacks such as Phone/Tablet Store Apps, .Net, ASP.Net, X-Box and with Xamarin iOS and Android. So writing your code in the PCL allows you to share the UI code to all platforms which are supported by the Xamarin.Forms framework which are:

  • iOS
    • iPhone/iPod
    • iPad & iPad Mini
  • Android
    • Phone
    • Tablet
  • Windows
    • Widnows Phone 8 & 8.1
    • Windows 8.1

The UI usually needs some tweaking when moving from one form factor to another but again some controls could be shared and with Xamarin.Forms they can be shared not only across factors but platforms. From a UI stand point Xamarin.Forms comes with limitations. The controls are a limited set and though they theoretically do allow to create a custom design it is currently not advised as the rendering will perform not as well than it’s Windows, Xamarin.iOS or Xamarin.Android UI counterparts.

Generally speaking as long as you are creating an app that can be created with standard components with minimal modifications Xamarin.Forms should serve you just fine.

That being said it is possible to write a part of the UI with Xamarin.Forms and integrate it with native screens. So one could start out with a Xamarin.Forms app and when you start bumping into performance issues on certain screens you can rewrite it for each platform and benefit from creating customized UIs and integrate to standard components such as login forms with Xamarin.Forms.

Integrating the platform

So Xamarin.Forms is an abstraction layer that allows developers to create UI’s once and then translates the UI to native UI controls on the specific platform. But what if you want to access the SDK of a given platform e.g. push notifications. With other cross platform approaches this often means you have to use a plugin that provides you the functionality for the platform. But as Xamarin.Forms builds on the full Xamarin stack you have full access to the SDK of the platform and are not limited by available plugins or SDK restrictions.

Limitations

So apart from not being great for designing highly customized apps are there any further limitations to Xamarin.Forms? I guess one of the biggest limitations to Xamarin.Forms at the moment is it’s age. It came out on 28. May 2014 and still is a 1.0 product, which are known for having some rough edges and Xamarin.Forms is no exception. So there are some issues that one may be bound to run into e.g. no UI designer, performance on data heavy views and the usual bugs that accompany V1.0 releases. That being said there is a huge interest in the Framework and it is already being used by a wide variety of apps i.e. fields. And given the recent efforts and releases of the team I believe Xamarin.Forms is a great option for certain types of applications.

Conclusion

We saw that Xamarin.Forms allows to develop native mobile apps for multiple platforms and thereby share the business logic and UI. Xamarin.Forms allows to write apps with XAML and is a great starting point for apps or writing prototypes. Because it integrates fully into the existing Xamarin stack there is no downside and switching between native UIs and Xamarin.Forms is a possibility for developers.

If your interested in the basic setup of a Xamarin.Forms app, here is a Hello World app that will run on Windows Phone, iOS and Android and shares all the XAML UI code.

This post was originally posted on the blog of Noser Engineering.

1 Comments

JSON Logo i.e. blog post logo

Though frowned upon often due to overuse inheritance remains a powerful and (when used correctly) great feature of an object oriented programming language such as C#. But when it comes down to serializing inheritance object structures i.e. deserializing them on the other side things tend to get hairy. The post will show you how serialization and deserialization of inheritance related objects can be performed with JSON.Net.

So lets have a look at the project setup. The server will be your standard ASP.Net Web API restful web service that comes with JSON.Net out of the box. On the client side we will be using consuming the service from a Portable Class Library PCL that will be able to run with most C# stacks e.g. Windows Store, .Net, Xamarin.iOS, Xamarin.Android etc.. I’ll be using a Xamarin.Forms app but the code will run just fine in your ever day WPF app. The basic system setup is the client calls the server for data, the server returns the data serialized as JSON which will then be deserialized on the client and then used to display the information to the user.

System overview showing communication flow from the client to the server and back via JSON serialized data.

So lets have a look how it works in more detail.

Setting up the project

Lets start with looking at the server which mainly exists of a controller:

public class InheritanceController : ApiController
{
// GET: api/Inheritance
public IEnumerable<ParentClass> Get()
{
return new ParentClass[] {new ParentClass(), new ChildClass()};
}
}

The controller creates a list of ParentClasses and ChildClasses before serializing them back to the caller.

public class ParentClass
{
public virtual string Title
{
get { return "Parent"; }
}

public virtual string Descirption
{
get { return "Hello from the parent."; }
}
}

public class ChildClass:ParentClass
{
public override string Title
{
get { return "Child"; }
}

public override string Descirption
{
get { return "The child says hi..."; }
}

public string ChildSecret
{
get { return "42"; }
}
}

So not a lot of magic going as you can see on the server side. So lets have a look at the client. In the PCL we will use the HTTP Client NuGet package to call the server and the JSON.Net package to deserialize the data from the server.

Nuget Package overview on the client showing JSON.NET, Microsoft BCL Build Components, MVVMLIght libraries only, Microsoft HTTP Client Libraries and Xamarin.Forms packages

On the client we will display the data in a list, you can see the UI code in the MainPage.xaml:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="InheritanceJsonSerialization.Client.Views.MainPage">
<Grid>
<ListView ItemsSource="{Binding DataItems}" ItemSelected="ListView_OnItemSelected" />
<ActivityIndicator IsRunning="{Binding IsLoading}" IsEnabled="{Binding IsLoading}" IsVisible="{Binding IsLoading}"/>
</Grid>
</ContentPage>

In the HttpHandler class in the GetData method the data is requested from the server and then deserialized.

using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using InheritanceJsonSerialization.Client.Models;
using Newtonsoft.Json;

namespace InheritanceJsonSerialization.Client.Services.Http.Impl
{
public class HttpHandler:IHttpHandler
{
private readonly HttpClient _httpClient;

public HttpHandler()
{
_httpClient = new HttpClient();
}

public async Task<IEnumerable<ParentClass>> GetData()
{
// Ensure that uri matches the service backend you are calling
//const string uri = "http://localhost:52890/api/inheritance";
const string uri = "https://inheritancejsonserializationweb.azurewebsites.net/api/inheritance";

var httpResult = await _httpClient.GetAsync(uri);
var jsonContent = await httpResult.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent);

return result;
}
}
}

Now when we deserialize the information on the client we run into the problem that the type information is not passed on to the client and therefore all objects deserialized are of type ParentClass.

Serializing with type information

Luckely JSON.Net allows us to easily include the type information when we serialize the type. On the server in the Register method within the WebApiConfig class we can setup how JSON.Net serializes objects:

public static void Register(HttpConfiguration config)
{
// Web API configuration and services
config.Formatters.JsonFormatter.SerializerSettings.TypeNameHandling = TypeNameHandling.All;

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}

Now the information will be serialized in the JSON string:

{
"$type": "InheritanceJsonSerialization.Models.ParentClass[], InheritanceJsonSerialization",
"$values": [
{
"$type": "InheritanceJsonSerialization.Models.ParentClass, InheritanceJsonSerialization",
"Title": "Parent",
"Descirption": "Hello from the parent."
},
{
"$type": "InheritanceJsonSerialization.Models.ChildClass, InheritanceJsonSerialization",
"Title": "Child",
"Descirption": "The child says hi...",
"ChildSecret": "42"
}
]
}

On the client side we will have to do a bit more work to get deserialization working.

Deserializing with Type information

For deserializing with type information you might have already found the following line of code that will trigger JSON.Net to check for the type information and try to deserialize it according to the information present in the JSON string.

            JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent, new JsonSerializerSettings{TypeNameHandling = TypeNameHandling.All});

The problem here is that all will go well when you serialize and deserialize from the same binary/namespace but in this setup (which I regard as the common setup) you will get an exception as the namespace will not exist i.e. be different on the client than on the server. To solve this issue we have to write a SerializationBinder that inherits from the DefaultSerializationBinder as follows:

public class InheritanceSerializationBinder : DefaultSerializationBinder
{
public override Type BindToType(string assemblyName, string typeName)
{
switch (typeName)
{
case "InheritanceJsonSerialization.Models.ParentClass[]": return typeof(ParentClass[]);
case "InheritanceJsonSerialization.Models.ParentClass": return typeof(ParentClass);
case "InheritanceJsonSerialization.Models.ChildClass[]": return typeof(ChildClass[]);
case "InheritanceJsonSerialization.Models.ChildClass": return typeof(ChildClass);
default: return base.BindToType(assemblyName, typeName);
}
}
}

This will simply map the server namespace to local types. Finally we can update the GetData method in the HttpHandler class:

public async Task<IEnumerable<ParentClass>> GetData()
{
// ...
var result = JsonConvert.DeserializeObject<IEnumerable<ParentClass>>(jsonContent, new JsonSerializerSettings{TypeNameHandling = TypeNameHandling.All, Binder = new InheritanceSerializationBinder()});

return result;
}

And now when we deserialize the list the ChildClass will be correctly identified i.e. the list will be preserved through deserialization.

Conclusion

In this post you saw how inheritance hirarchies can be correctly serialized and deserialized on the client using JSON.Net. By doing so we had to configure our ASP.Net Web API and add handling mechanisms on the client side. I hope this post is of any help and please let me know if I may have mist anything Smile

You can find the code on GitHub.

0 Comments

StorageImage

A lot of applications have to persist application data or state. When developing mobile applications with C# such as for Windows or with Xamarin for iOS and Android it is a common approach to share your business logic and backend implementations in the Portable Class Library (PCL). In this blog post we’ll look at how we can also implement storage within the PCL and therefore will only need to implement the storage services once. We will be focusing on the following topics:

  1. Setting up the project
  2. Storing and loading objects to files
  3. Storing/using binary data such as images

So lets start off by setting up the project. I’ll be demonstrating the sample with a Xamarin.Forms project as it allows me to quickly develop, deploy and test an app on all three major mobile platforms. But as the code is in the PCL you can use the exact same approach to implement the system in Windows Store, WPF etc. applications.

Setting up the project

Lets create an app that lists Companies by name, URL and displays the company logo. To do this we will create a view that will display the content as follows:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinFormsOfflineStorage.Views.MainPage">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Text="Refresh" Command="{Binding UpdateCompaniesCommand}"></Button>
<ListView ItemsSource="{Binding Companies}" Grid.Row="1">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell Text="{Binding Name}" ImageSource="{Binding ImageUri}" Detail="{Binding ImageDescription}"></ImageCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ActivityIndicator Grid.Row="1" IsRunning="{Binding IsLoadingData}"></ActivityIndicator>
</Grid>
</ContentPage>

The data is provided by a View Model that is based upon the MVVM Light framework by Laurent Bugnion. I wrote a post a while ago on how to get started with MVVM Light and Xamarin.Forms.

public class MainViewModel:ViewModelBase
{
private readonly ICompanyService _companyService;
private bool _isLoadingData;

public MainViewModel(ICompanyService companyService)
{
if (companyService == null) throw new ArgumentNullException("companyService");
_companyService = companyService;

Companies = new ObservableCollection<Company>();
IsLoadingData = false;
UpdateCompaniesCommand = new RelayCommand(UpdateCompanies, () => !IsLoadingData);
}

public bool IsLoadingData
{
get { return _isLoadingData; }
set
{
if (value == _isLoadingData) return;
_isLoadingData = value;
RaisePropertyChanged(() => IsLoadingData);
}
}

public ObservableCollection<Company> Companies { get; set; }

public ICommand UpdateCompaniesCommand { get; set; }

public async Task Init()
{
await UpdateCompaniesList();
}

private async void UpdateCompanies()
{
IsLoadingData = true;

await _companyService.UpdateCompanies();
await UpdateCompaniesList();

IsLoadingData = false;
}

private async Task UpdateCompaniesList()
{
var companies = await _companyService.GetCompanies();

Companies.Clear();

foreach (var company in companies)
{
Companies.Add(company);
}
}
}

Which calls a CompanyService that calls the backend:

// ...

public async Task UpdateCompanies()
{
// URL should point to where your service is running
const string uri = "http://offlinestorageserver.azurewebsites.net/api/values";
var httpResult = await _httpClient.GetAsync(uri);
var jsonCompanies = await httpResult.Content.ReadAsStringAsync();

var companies = JsonConvert.DeserializeObject<ICollection<Models.Company>>(jsonCompanies);
_companies = companies;
}

// ...

And provides a list of companies:

public IEnumerable<Models.Company> GetCompanies()
{
return _companies;
}

Now lets look on how we can store this list to the “disk” and display the information even if the app is started when there is no connection to the backend.

Enabling storage access in the PCL

Thanks to Daniel Plaisted accessing the file storage from within the PCL of your applications is actually really easy. All that is left to do for us is installing the NuGet package PCL Storage. Ensure that you install it not only for the PCL but only for the platforms you are targeting with your app:

PclStorageNugetInstall

Before we store lets just still quickly have a look at where we actually want to store the files. The PCL storage provides a start location which can be accessed by calling the FileSystem.Current.LocalStorage property. This will return an IFolder object which can be allows navigating to further folders by invoking the GetFolder method, alternatively the CreateFolder method can also be used with the collision option OpenIfExists, I generally use the second approach as it allows to write less code. So if we want to store our data in a folder within the root location of the local storage it would be done as follows:

private static async Task<IFolder> NavigateToFolder(string targetFolder)
{
IFolder rootFolder = FileSystem.Current.LocalStorage;
IFolder folder = await rootFolder.CreateFolderAsync(targetFolder,
CreationCollisionOption.OpenIfExists);

return folder;
}

As you can see the PCL Storage embraces the Async/Await pattern nicely and therefore will not block your app i.e. UI when working against the file system. Now lets get down to storing some data.

Persist an object

Now lets first store the list of objects we receive from our service into a file. As I’m already using JSON.Net for deserializing the data that comes from our service I’ll be using this library to serialize our objects to a JSON string and then store the now text data to a file in the SerializeCompanies method:

private static async Task SerializeCompanies(IFolder folder, ICollection<Models.Company> companies)
{
IFile file = await folder.CreateFileAsync(CompaniesFileName, CreationCollisionOption.ReplaceExisting);
var companiesString = JsonConvert.SerializeObject(companies);
await file.WriteAllTextAsync(companiesString);
}

As you can see files are created similarly to folders but differ in the collision option. It generally is a generally easier to handle merging of data in the C# memory world itself (given that the list is not to large for this) and then simply overwriting the preexisting cache.

Loading the data object

We can now update the GetCompanies method to return the list when we call it.

public async Task<IEnumerable<Models.Company>> GetCompanies()
{
return _companies ?? (_companies = await ReadCompaniesFromFile());
}

Once the data has been persisted by the website we do no longer require an internet connection to present the user with the information. And we can simply read them from a file as in ReadCompaniesFromFile:

private async Task<IEnumerable<Models.Company>>  ReadCompaniesFromFile()
{
var folder = await NavigateToFolder(CompaniesFolder);

if ((await folder.CheckExistsAsync(CompaniesFileName)) == ExistenceCheckResult.NotFound)
{
return new List<Models.Company>();
}

IFile file = await folder.GetFileAsync(CompaniesFileName);
var jsonCompanies = await file.ReadAllTextAsync();

if (string.IsNullOrEmpty(jsonCompanies)) return new List<Models.Company>();

var companies = JsonConvert.DeserializeObject<IEnumerable<Models.Company>>(jsonCompanies);

return companies;
}

Now the object data is persisted but we haven’t yet stored the images which is not text data but binary data. So lets see how we can store images to the file system.

Store binary data

To store the images we will have to get the images and store the binary data from the web to a file. This is done using the file stream of the opened file in the StoreImagesLocallyAndUpdatePathmethod:

private async Task StoreImagesLocallyAndUpdatePath(IFolder folder, IEnumerable<Models.Company> companies)
{
foreach (var company in companies)
{
var file = await folder.CreateFileAsync(company.Name + ".jpg", CreationCollisionOption.ReplaceExisting);
using (var fileHandler = await file.OpenAsync(FileAccess.ReadAndWrite))
{
var httpResponse = await _httpClient.GetAsync(company.ImageUri);
byte[] imageBuffer = await httpResponse.Content.ReadAsByteArrayAsync();
await fileHandler.WriteAsync(imageBuffer, 0, imageBuffer.Length);

company.ImageUri = file.Path;
}
}
}

Streams should always be disposed or else memory leaks will occur so the stream is wrapped in a using block. For storing the binary data we download the image via the URL provided and read the content into a byte array which allows us to easily pass it into the stream so it can get stored. Finally we replace the ImageUri data in the POCO (Plain Old CLR Object) before it gets serialized.

I recommend that you use the file endings according to the data you are storing. Certain containers rely on the information so as long as the good practice is kept up we are not running the risk of having to debug a strange error of information not showing up on the screen.

Loading images

Now we could load the images back into memory but as images are somewhat a special case the local path / ImageUri alone is enough to be set in the image control. So we actually do not have to change any code in the UI or add any additional handling as the image control will simply now load the image from the local storage.

Conclusion

In this post we saw how we can setup our projects to store files directly out of the PCL. We stored a data object i.e. text data to a file and proceeded to store an image/binary data. I think a big thank you is due to Daniel Plaisted as his work really streamlines persisting data with from the PCL.

You can find the entire code on GitHub.

References

Title Image by Dr. Hannes Grobe under Creative Commons V3

0 Comments

RESTXamarintTitleLogo

Lets have a look at how we can consume a REST based web service in a Xamarin.Forms application. In this blog post we will look at how an ASP.Net WebAPI service that is hosted on Azure and how it can be consumed in the Portable Class Library (PCL) of your Xamarin.Forms application and write a small UI to interact with the REST service. Please note that I used Visual Studio 2013 while creating the example for this project.

 

Creating the backend

An ASP.Net WebAPI can be considered as a headless website, so many of the concepts of ASP.Net MVC apply but we will not be writing any HTML, JavaScript and CSS code for displaying the data as it will simply provide the data through the controller. Per default the controller can return the data serialized to JSON or XML. For this example I have created two controllers, one will just simply return a string and return it as the content of the HTTP package:

public class BasicController : ApiController
{
// GET: api/Basic/5
public string Get(int id)
{
return string.Format("You entered: {0}", id);
}
}

The second one will return a serialized object to the caller. The default settings will request the data to be serialized with JSON but we will come to that later on. The second controller looks as follows:

public class ObjectController : ApiController
{
// GET: api/Object/5
public NumberWrapper Get(int id)
{
return new NumberWrapper{WrappedNumber = string.Format("You entered: {0}", id)};
}
}

And the Plain Old CLR Object (POCO) which is used you can see here:

public class NumberWrapper
{
public string WrappedNumber { get; set; }
}

So all pretty straight forward, now lets look at how we can consume the service once it is running.

Note: You can publish this webservice on Azure which makes it really easy to access it from phones and other Virtual Machines (VMs) as you will not be hassled with firewall settings and therefore can focus at the task at hand.

 

Consuming a REST service in the PCL

For consuming the REST service we will need to install the WebHttpClient NuGet package from Microsoft. So lets open up the package manager by right-clicking on the solution and then searching for WebHttpClient, add the NuGet package to the PCL, Android, iOS and Windows Phone Project. For deserializing the JSON we will use the JSON.Net library from James Newton-King, so search once more for JSON.Net and install it again for all the client projects.

The communication with the backend is created in HttpWrapper.cs, the BasicController simply the Content of the result is read and passed back:

public async Task<string> GetBasicDataAsync(int i)
{
var uri = string.Format("https://xamarinwebapiservice.azurewebsites.net/api/basic/{0}", i);

var result = await _httpClient.GetAsync(uri);

return await result.Content.ReadAsStringAsync();
}

When we call the ObjectController we receive the JSON in the Content of the result and have to deserialize it first:

public async Task<NumberWrapper> GetNumberWrapperDataAsync(int i)
{
var uri = string.Format("{0}object/{1}", BaseUrl, i);

var result = await _httpClient.GetAsync(uri);

var jsonNumberWRapper = await result.Content.ReadAsStringAsync();

return JsonConvert.DeserializeObject<NumberWrapper>(jsonNumberWRapper);
}

So far so good now lets create a small UI to Consume the service and its controllers.

 

The client UI

I’ll be using MVVM Light in the UI for the data binding, on a former post you can find an introduction on how to get started with MVVM Light. The UI lets you pick a number and you can choose the call by selecting the according button:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="WebApiXamarinForms.View.MainPage">
<StackLayout>
<Picker SelectedIndex="{Binding SelectedNumberIndex}" HorizontalOptions="CenterAndExpand" Title="Numbers">
<Picker.Items>
<x:String>1</x:String>
<x:String>2</x:String>
<x:String>3</x:String>
<x:String>4</x:String>
<x:String>5</x:String>
<x:String>6</x:String>
<x:String>7</x:String>
<x:String>8</x:String>
<x:String>9</x:String>
<x:String>10</x:String>
</Picker.Items>
</Picker>
<Button Text="Basic Submit" Command="{Binding BasicSubmitCommand}" HorizontalOptions="CenterAndExpand"></Button>
<Button Text="Object Submit" Command="{Binding ObjectSubmitCommand}" HorizontalOptions="CenterAndExpand"></Button>
<ActivityIndicator IsRunning="{Binding CallingService}"></ActivityIndicator>
<Label Text="{Binding Response}" VerticalOptions="Center" HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage>

Note that the Picker control does not yet support data binding so this is currently the only way how you can set the values.

In the MainViewModel.cs the calls to the service are made during the command invokes and the result is written accordingly to the UI. Here the BasicSubmitCommand:

private async void GetBasicResponseAsync()
{
CanGetBasicResponse = false;
CallingService = true;

Response = await _webService.GetBasicDataAsync(_numbers[SelectedNumberIndex]);

CallingService = false;
CanGetBasicResponse = true;
}

And the ObjectSubmitCommand:

private async void GetObjectResponseAsync()
{
CanGetBasicResponse = false;
CallingService = true;

var numberWrapper = await _webService.GetNumberWrapperDataAsync(_numbers[SelectedNumberIndex]);
Response = numberWrapper.WrappedNumber;

CallingService = false;
CanGetBasicResponse = true;
}

Conclusion

In this blog post we took a quick look at how a WebAPI controller is setup. Further we looked at how HTTP calls are created on the Xamarin.Forms client and how responses can be parsed and used within a program. We also saw how we can consume objects that are received as JSON strings from a web service.

You can find the entire source code on GitHub.