AZURE MOBILE SERVICE IOS EXCEPTION & SOLUTION

AZURE MOBILE SERVICE IOS EXCEPTION & SOLUTION

So you have Xamarin and the Azure Mobile Services SDK installed. You created an Azure Mobile Service and decided to build an iOS app.  Rather than using the TODO sample app that is built for you and has a lot of pre-built UI and code that you may not need you decide to build your own app. Great so you follow the instructions on the Azure Mobile Services Quick Start Page, specifically the “CONNECT AN EXISTING XAMARIN APP” Those instructions tell you to do the following:

  1. In your project, right-click the component node and select Get More Components; this opens the Component Store window. Search the store for “Azure Mobile Services,” then add the component to your project.
  2. Add “using Microsoft.WindowsAzure.MobileServices;“, then copy and paste the following code into your AppDelegate.cs file:
public static MobileServiceClient MobileService = new MobileServiceClient(
    "<your mobile service URI goes here>",
    "<your api key goes here>"
);

It follows with some instructions to store data in your mobile service by creating an Item table and instructions on how to insert an item into the table…

All of this sounds good and simple but… You quickly find out that it doesn’t compile…  You need to add a reference to System.Net.Http.  Easy enough fix so you add the reference and it compiles, but you see a warning…

Found conflicts between different versions of the same dependent assembly. Please set the “AutoGenerateBindingRedirects” property to true in the project file. For more information, see http://go.microsoft.com/fwlink/?LinkId=294190.

Hrmp… Will that be a problem?  Well being the adventurous/impatient type you ignore the warning and just run it…

You receive the following delightful exception:

System.TypeInitializationException: An exception was thrown by the type initializer for iOSClientApp.AppDelegate

Ugh, perhaps that warning was important… So you follow the instructions at the link http://go.microsoft.com/fwlink/?LinkId=294190 Those instructions basically tell you to add an entry into your project file:

<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects></span>

Microsoft is kind enough to provide you with an excerpt of a project file that helps you understand where to put the entry as shown below:

<?xml version="1.0" encoding="utf-8"?>
   <Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
     <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
     <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == ''     ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
        <ProjectGuid>{123334}</ProjectGuid>
        ...
        <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     </PropertyGroup>
     ...
   </Project>
...

Feeling good, thinking that your Sherlock like Bing(ing) skills have found the resolution to the problem you then re-build your app.

Great the warning is gone! So you run it.

Hrmp… It still does not  work and provides you with the same exception as before…. Now what?

Well you try that trusty old TODO sample that is prebuilt for you and it works… Ok so your environment is ok, your mobile service is ok, what’s up, why don’t the instructions for “CONNECTING AN EXISTING XAMARIN APP” work?

You decide to create a simple app, that includes the “Azure Mobile Service” component and does nothing except include that one line of code you were told to add.

public static MobileServiceClient MobileService = new MobileServiceClient(
    "<your mobile service URI goes here>",
    "<your api key goes here>"
);

You of course add the missing System.Net.Http reference and that project entry to remove the warning as well. Holding your breath a bit, you then run it.

Hrmp… That same lovely exception is still presented to you.

As a determined chap you don’t give up, you try to figure out why the TODO app runs and your app doesn’t. You look at the references and notice that there are several more references in the TODO app than in yours. You also notice that the TODO app didn’t use the component strategy to include the Azure Mobile Services client, they used Nuget packages.. Hmm… Ok so you try to replicate this by creating a new app this time including the same Nuget packages.  This time all of the references are there, so is the warning, you notice that the TODO app also has the warning but it works… So you run your simple app that does nothing except has that one line of code in it.

public static MobileServiceClient MobileService = new MobileServiceClient(
    "<your mobile service URI goes here>",
    "<your api key goes here>"
);

Hrmp… That same lovely exception is still presented to you…

Ok this is certainly a stubborn little problem… You then dig into the code of the TODO app and notice something interesting… The app does not perform a static initialization of the MobileServiceClient. Hmm… You look a bit further and also notice that there is a call to CurrentPlatform.Init(); A bit of glee and excitement starts to flow through your fingers. You change your app to follow the same pattern. Your code looks something like this:

File: MobileServiceHelper.cs
using Microsoft.WindowsAzure.MobileServices;
public class MobileServiceHelper
{
    static MobileServiceHelper instance = new MobileServiceHelper();

    const string applicationURL = @"<your mobile service URI goes here>";
    const string applicationKey = @"<your key goes here>";

    private readonly MobileServiceClient _client;

    private MobileServiceHelper()
    {
         // Initialize the Portable Class Libraries so the correct version of
         // Microsoft.WindowsAzure.Mobile.Ext is loaded
         CurrentPlatform.Init();

         // Initialize the Mobile Service client with your URL and key
         _client = new MobileServiceClient(applicationURL, applicationKey);
    }

    public MobileServiceClient ServiceClient { get { return _client; } }
    public static MobileServiceHelper DefaultService
    {
        get
        {
             return instance;
        }
    }
}

You then make a change to your ViewController’s ViewDidLoad() method to get a reference to your singleton to ensure that it works like this:

File: xxxViewControler.cs
   ...
   private MobileServiceHelper client;

   #region View lifecycle

   public override void ViewDidLoad()
   {
      base.ViewDidLoad();

      // Perform any additional setup after loading the view, typically from a nib.
      client = MobileServiceHelper.DefaultService;
   }
...

With trepidation and excitement you build and run your app and IT WORKS! No exception.  You go on to add the code to call your mobile service to ensure that it “really” works, and everything proceeds as it should.

So it turns out that those simple two steps that you see under the “CONNECT AN EXISTING XAMARIN APP” on the Mobile Service Dashboard quick start appear to be incorrect.

Note:
It turns out that the only Nuget packages you need and you do in fact need the BOTH, when you are using offline features, are the WindowsAzure.MobileServices and WindowsAzure.MobileServices.SQLiteStore Nuget packages.

Initially I was seeing an issue that occurred without the SQLiteStore Nuget package. Specifically I was not getting the necessary reference to Microsoft.WindowsAzure.Mobile.Ext. However when I used the package manager console to install the Nuget package (e.g. PM> Install-Package WindowsAzure.MobileServices) the reference to Microsoft.WindowsAzure.Mobile.Ext was properly added.  The addition of the reference did not occur reliably when I used the Nuget Package manager for solutions user interface.  It could be fixed now, your mileage may vary…

 

I hope this helps save you some time…

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>