Skip to content

Instantly share code, notes, and snippets.

@chrisriesgo
Created July 19, 2016 21:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisriesgo/1c73c6f03d6b01f752e8da5d5dfa89b6 to your computer and use it in GitHub Desktop.
Save chrisriesgo/1c73c6f03d6b01f752e8da5d5dfa89b6 to your computer and use it in GitHub Desktop.

Add an Azure Backend to Your Mobile App
Part 2 - Connect Client Apps

The Azure backend that was setup in the previous step is for a Todo List app.

In this next step, we will build a simple Todo List app. By the end you should be able to manage a simple todo list by adding, updating, and deleting todo items.

1. Create New Mobile App(s)

Create a new mobile client app project. Follow the instructions for Visual Studio on Windows or Xamarin Studio on Mac.

  • Open Visual Studio
    • Create a new Xamarin Forms project
      1. File > New Project
      2. Select the Visual C# > Cross-Platform > Blank Xaml App (Xamarin.Forms Portable)
      3. Configure your app
        • Give your project a name
        • Give your solution a name
        • Leave the rest set to their defaults
  • or Open Xamarin Studio
    • Create a new Xamarin Forms project
      1. File > New Solution
      2. Select a Multiplatform App > Forms App
      3. Configure your app
        • Give your app a name
        • Choose to share code using a Portable Class Library
        • Leave the rest set to their defaults

Be On the Lookout

  • If prompted with Xamarin Mac Agent Instructions window, please disregard and click the OK button.

  • If prompted with the Xamarin Mac Agent window and shows a mac connected to your network, please disregard and click the Close button.

  • If prompted to Enable Developer Mode for Windows 10, please disregard and click the OK button.

  • If prompted with a New Universal Windows Project window, to choose the minimum and target platform versions for a Universal Windows application, select the minimum / lowest build number for both.

  • If you receive any errors related to Windows, Windows Phone, or UWP projects, please disregard and close the popups. We will not be walking through Windows project examples in this exercise. If this continues to be an issue, please delete the Windows, Windows Phone, and UWP projects.

2. Delete the Default Files

Delete the default Page.xaml file that was added to your Portable project.

  1. Right-click the file
    • MainPage.xaml (Windows)
    • or AppNamePage.xaml (Mac)
  2. Select Delete from the popup menu
  3. Confirm delete

3. Add NuGet Packages

Add the Azure Mobile Client SDK and App Service Helpers NuGet packages to each of these projects in your solution

  • AppName (Portable) - Portable Class Library (PCL)
  • AppName**.Droid** - Mobile Android project

Add the Azure Mobile Client SDK Package

  1. Open NuGet Package Manager
    1. Right-click the project
    2. Select Manage NuGet Packages
  2. Tap the Browse tab, then Search for Microsoft.Azure.Mobile.Client
  3. Select Azure Mobile SQLiteStore
  4. Click the Install button
  5. Popups may ask to review or include a few more packages. Tap OK / I Accept.
  6. Select Azure Mobile Client SDK
  7. Click the Install button
  8. Popups may ask to review or include a few more packages. Tap OK / I Accept.

Add the App Service Helpers Package

  1. Open NuGet Package Manager
    1. Right-click the project
    2. Select Manage NuGet Packages
  2. Tap the Browse tab, then Search for AppService.Helpers
  3. Select App Service Helpers
  4. Click the Install button
  5. Popups may ask to review or include a few more packages. Tap OK / I Accept.
  6. Select App Service Helpers for Xamarin Forms
  7. Click the Install button
  8. Popups may ask to review or include a few more packages. Tap OK / I Accept.

Don't forget to install the NuGet packages for both projects:

  • AppName (Portable) - Portable Class Library (PCL)
  • AppName**.Droid** - Mobile Android project

4. Setup the Android Project

The following steps are for your AppName__.Droid__ project.

Update the MainActivity class

  1. Open MainActivity.cs file
  2. Replace the MainActivity class definition with this:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
	protected override void OnCreate(Bundle bundle)
	{
		base.OnCreate(bundle);
	
		global::Xamarin.Forms.Forms.Init(this, bundle);
		Microsoft.WindowsAzure.MobileServices.CurrentPlatform.Init();
		LoadApplication(new App());
	}
}

Be sure to have the following using statements in the MainActivity file:

using Android.App;
using Android.Content.PM;
using Android.OS;

Save your changes to MainActivity (Ctrl+S).

Make the Android project the startup project

  1. Right-click your AppName**.Droid** project
  2. Select Set as StartUp Project from the popup menu

That’s it. Your Android project is all set up!

5. Setup the Portable Class Library / Xamarin Forms App

The following steps are for your AppName (Portable) project

Add the Constants class

  1. Right-Click the Project: Add > New Item
  2. Select Visual C# > Class
  3. Name the file Constants.cs

Update the Constants class

  1. Open the Constants.cs file
  2. Replace the Constants class definition with this:
public static class Constants
{
	// Replace strings with your mobile services and gateway URLs.
	public static string ApplicationURL = @"https://yourname-appservicehelper.azurewebsites.net";
}

Replace the ApplicationURL string with the URL of your Azure Mobile app

Save your changes to Constants.cs (Ctrl+S).

Add the TodoItem class

  1. Right-Click the Project: Add > New Item
  2. Select Visual C# > Class
  3. Name the file TodoItem.cs

Update the TodoItem class

  1. Open the TodoItem.cs file
  2. Replace TodoItem class definition with this:
public class TodoItem : EntityData
{
	string id;
	string name;
	bool done;
	
	[JsonProperty(PropertyName = "id")]
	public string Id
	{
		get { return id; }
		set { id = value; }
	}
	
	[JsonProperty(PropertyName = "text")]
	public string Name
	{
		get { return name; }
		set { name = value; }
	}
	
	[JsonProperty(PropertyName = "complete")]
	public bool Done
	{
		get { return done; }
		set { done = value; }
	}
}

Be sure to have the following using statements in the TodoItem file:

using Newtonsoft.Json;
using AppServiceHelpers.Models;

Save your changes to TodoItem.cs (Ctrl+S).

Add the TodoList page

  1. Right-Click the Project > Add > New Item
  2. Select Visual C# > Cross-Platform > Forms Xaml Page
  3. Name the file TodoList.xaml

This will create a TodoList.xaml and associated TodoList.xaml.cs file.

Update the TodoList page

  1. Open the TodoList.xaml file
  2. Replace the ContentPage body section noted in the code snippet below:
<?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="App1.Page1">
   
  	// ************* TODO: Replace this section *************
	<Label Text="{Binding MainText}" VerticalOptions="Center" HorizontalOptions="Center" />
	// ******************************************************
	
</ContentPage>

with this:

<Grid RowSpacing="0">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <ActivityIndicator Grid.RowSpan="2"
                     HorizontalOptions="Center"
                     VerticalOptions="Center"
                     IsVisible="False"
                     IsEnabled="True"
                     x:Name="syncIndicator"/>
  <StackLayout Grid.Row="0" BackgroundColor="#5ABAFF" Padding="10,30,10,5">
    <Label TextColor="#555555" Text="Azure App Service" />
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition Width="Auto"/>
      </Grid.ColumnDefinitions>
      <Entry x:Name="newItemName"
                Placeholder="Item name" />
      <StackLayout x:Name="buttonsPanel" Grid.Column="1" Orientation="Horizontal" HorizontalOptions="StartAndExpand">
        <Button Text="+"
                MinimumHeightRequest="30"
                Clicked="OnAdd" />
      </StackLayout>
    </Grid>
  </StackLayout>
  <ListView x:Name="todoList"
			ItemSelected="OnSelected"
			IsPullToRefreshEnabled="true" Refreshing="OnRefresh"
			Grid.Row="1">
    <ListView.ItemTemplate>
      <DataTemplate>
        <ViewCell>
          <ViewCell.ContextActions>
            <MenuItem Clicked="OnComplete" Text="Complete" CommandParameter="{Binding .}"/>
          </ViewCell.ContextActions>
          <StackLayout HorizontalOptions="StartAndExpand" Orientation="Horizontal" Padding="15,5,0,0">
            <StackLayout Padding="5,0,0,0" VerticalOptions="StartAndExpand" Orientation="Vertical">
              <Label Text="{Binding Name}"  />
            </StackLayout>
          </StackLayout>
        </ViewCell>
      </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>
</Grid>

Save your changes to TodoList.xaml (Ctrl+S).

Update the TodoList code-behind

  1. Open the TodoList.xaml.cs file
  2. Replace the TodoList class definition with this:
public partial class TodoList : ContentPage
{
	IEasyMobileServiceClient _client;
	
	public TodoList(IEasyMobileServiceClient client)
	{
		InitializeComponent();
		_client = client;
	}
	
	protected override async void OnAppearing()
	{
		base.OnAppearing();
	
		// Set syncItems to true in order to synchronize the data on startup when running in offline mode
		await RefreshItems(true, syncItems: true);
	}
	
	// Data methods
	async Task AddItem(TodoItem item)
	{
		await _client.Table<TodoItem>().AddAsync(item);
		todoList.ItemsSource = await _client.Table<TodoItem>().GetItemsAsync();
	}
	
	async Task CompleteItem(TodoItem item)
	{
		item.Done = true;
		await _client.Table<TodoItem>().UpdateAsync(item);
		todoList.ItemsSource = await _client.Table<TodoItem>().GetItemsAsync();
	}
	
	public async void OnAdd(object sender, EventArgs e)
	{
		var todo = new TodoItem { Name = newItemName.Text };
		await AddItem(todo);
	
		newItemName.Text = string.Empty;
		newItemName.Unfocus();
	}
	
	// Event handlers
	public async void OnSelected(object sender, SelectedItemChangedEventArgs e)
	{
		var todo = e.SelectedItem as TodoItem;
		if(Device.OS != TargetPlatform.iOS && todo != null)
		{
			// Not iOS - the swipe-to-delete is discoverable there
			if(Device.OS == TargetPlatform.Android)
			{
				await DisplayAlert(todo.Name, "Press-and-hold to complete task " + todo.Name, "Got it!");
			}
			else
			{
				// Windows, not all platforms support the Context Actions yet
				if(await DisplayAlert("Mark completed?", "Do you wish to complete " + todo.Name + "?", "Complete", "Cancel"))
				{
					await CompleteItem(todo);
				}
			}
		}
	
		// prevents background getting highlighted
		todoList.SelectedItem = null;
	}
	
	// http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#context
	public async void OnComplete(object sender, EventArgs e)
	{
		var mi = ((MenuItem)sender);
		var todo = mi.CommandParameter as TodoItem;
		await CompleteItem(todo);
	}
	
	// http://developer.xamarin.com/guides/cross-platform/xamarin-forms/working-with/listview/#pulltorefresh
	public async void OnRefresh(object sender, EventArgs e)
	{
		var list = (ListView)sender;
		Exception error = null;
		try
		{
			await RefreshItems(false, true);
		}
		catch(Exception ex)
		{
			error = ex;
		}
		finally
		{
			list.EndRefresh();
		}
	
		if(error != null)
		{
			await DisplayAlert("Refresh Error", "Couldn't refresh data (" + error.Message + ")", "OK");
		}
	}
	
	public async void OnSyncItems(object sender, EventArgs e)
	{
		await RefreshItems(true, true);
	}
	
	private async Task RefreshItems(bool showActivityIndicator, bool syncItems)
	{
		using(var scope = new ActivityIndicatorScope(syncIndicator, showActivityIndicator))
		{
			todoList.ItemsSource = await _client.Table<TodoItem>().GetItemsAsync();
		}
	}
	
	private class ActivityIndicatorScope : IDisposable
	{
		private bool showIndicator;
		private ActivityIndicator indicator;
		private Task indicatorDelay;
	
		public ActivityIndicatorScope(ActivityIndicator indicator, bool showIndicator)
		{
			this.indicator = indicator;
			this.showIndicator = showIndicator;
	
			if(showIndicator)
			{
				indicatorDelay = Task.Delay(2000);
				SetIndicatorActivity(true);
			}
			else
			{
				indicatorDelay = Task.FromResult(0);
			}
		}
	
		private void SetIndicatorActivity(bool isActive)
		{
			this.indicator.IsVisible = isActive;
			this.indicator.IsRunning = isActive;
		}
	
		public void Dispose()
		{
			if(showIndicator)
			{
				indicatorDelay.ContinueWith(t => SetIndicatorActivity(false), TaskScheduler.FromCurrentSynchronizationContext());
			}
		}
	}
}

Be sure to have the following using statements in the TodoList file:

using System;
using System.Threading.Tasks;
using Xamarin.Forms;
using AppServiceHelpers.Abstractions;

Save your changes to TodoList.xaml.cs (Ctrl+S).

Update the App class

  1. Open the App.xaml.cs file
  2. Replace the App class definition with this:
public partial class App : Application
{
	public App()
	{
		InitializeComponent();
	
		// 1. Create a new EasyMobileServiceClient.
		var client = EasyMobileServiceClient.Create();
	
		// 2. Initialize the library with the URL of the Azure Mobile App you created in Step #1.
		// Example: http://appservicehelpers.azurewebsites.net
		client.Initialize(Constants.ApplicationURL);
	
		// 3. Register a model with the EasyMobileServiceClient to create a table.
		client.RegisterTable<TodoItem>();
	
		// 4. Finalize the schema for our database. All table registrations must be done before this step.
		client.FinalizeSchema();
	
		// The root page of your application
		MainPage = new TodoList(client);
	}
	
	protected override void OnStart()
	{
		// Handle when your app starts
	}
	
	protected override void OnSleep()
	{
		// Handle when your app sleeps
	}
	
	protected override void OnResume()
	{
		// Handle when your app resumes
	}
}

Be sure to have the following using statements in the App.xaml.cs file:

using AppServiceHelpers;
using Xamarin.Forms;

Save your changes to App.xaml.cs (Ctrl+S).

6. Run the App

  1. Select an Android emulator from the IDE's dropdown list
  2. Run the App by pressing F5 or selecting Start Debugging from the Build menu.

The application should build and then deploy to the emulator.

Explore the app.

  • add several new todo items
  • mark a few as complete
  • delete one

Head back to Finish and Verify

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment