Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
..
Failed to load latest commit information.
Finish
Start
README.md
Speaker.csv
appsettingsfix.png Updated with Azure issue workaround Nov 11, 2016

README.md

Xamarin Dev Days Hands On Lab

Today we will build a cloud connected Xamarin.Forms application that will display a list of Xamarin Dev Days speaker. We will start by building the business logic backend that pulls down json-ecoded data from a RESTful endpoint. Then we will connect it to an Azure Mobile App backend in just a few lines of code.

Mobile App Walkthrough

1. Open Solution in Visual Studio

  1. Open Start/DevDaysSpeakers.sln

This solution contains 4 projects

  • DevDaysSpeakers - Shared Project that will have all shared code (model, views, and view models)
  • DevDaysSpeakers.Droid - Xamarin.Android application
  • DevDaysSpeakers.iOS - Xamarin.iOS application (requires a macOS build host)
  • DevDaysSpeakers.UWP - Windows 10 UWP application (requires Visual Studio 2015/2017 on Windows 10)

Solution

The DevDaysSpeakers project also has blank code files and XAML pages that we will use during the Hands on Lab.

2. NuGet Restore

All projects have the required NuGet packages already installed, so there will be no need to install additional packages during the Hands on Lab. The first thing that we must do is restore all of the NuGet packages from the internet.

  1. Right-click on the Solution and selecting Restore NuGet packages...

Restore NuGets

3. Model

We will download details about the speakers.

  1. Open Speaker.cs
  2. In Speaker.cs, copy/paste the following properties:
public string Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string Website { get; set; }
public string Title { get; set; }
public string Avatar { get; set; }

4. Implementing INotifyPropertyChanged

INotifyPropertyChanged is important for data binding in MVVM Frameworks. This is an interface that, when implemented, lets our view know about changes to the model.

  1. In Visual Studio, open SpeakersViewModel.cs
  2. In SpeakersViewModel.cs, implement INotifyPropertyChanged by changing this
public class SpeakersViewModel
{

}

to this

public class SpeakersViewModel : INotifyPropertyChanged
{

}
  1. In SpeakersViewModel.cs, right click on INotifyPropertyChanged
  2. Implement the INotifyPropertyChanged Interface
    • (Visual Studio Mac) In the right-click menu, select Quick Fix -> Implement Interface
    • (Visual Studio PC) In the right-click menu, select Quick Actions and Refactorings -> Implement Interface
  3. In SpeakersViewModel.cs, ensure this line of code now appears:
public event PropertyChangedEventHandler PropertyChanged;
  1. In SpeakersViewModel.cs, create a new method called OnPropertyChanged
    • Note: We will call OnPropertyChanged whenever a property updates
private void OnPropertyChanged([CallerMemberName] string name = null)
{

}
  1. Add code to OnPropertyChanged:
    • Visual Studio Mac and Visual Studio PC 2017 or newer
private void OnPropertyChanged([CallerMemberName] string name = null) =>
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    • Visual Studio PC 2015 or earlier
private void OnPropertyChanged([CallerMemberName] string name = null)
{
    var changed = PropertyChanged;

    if (changed == null)
       return;

    changed.Invoke(this, new PropertyChangedEventArgs(name));
}

5. Implementing IsBusy

We will create a backing field and accessors for a boolean property. This property will let our view know that our view model is busy so we don't perform duplicate operations (like allowing the user to refresh the data multiple times).

  1. In SpeakersViewModel.cs, create the backing field:
public class SpeakersViewModel : INotifyPropertyChanged
{
    private bool isBusy;
    //...
}
  1. Create the property:
public class SpeakersViewModel : INotifyPropertyChanged
{
    //...
    public bool IsBusy
    {
        get { return isBusy; }
        set
        {
            isBusy = value;
            OnPropertyChanged();

            GetSpeakersCommand.ChangeCanExecute();
        }
    }
    //...
}

Notice that we call OnPropertyChanged when the value changes. The Xamarin.Forms binding infrastructure will subscribe to our PropertyChanged event so the UI will be notified of the change.

6. Create ObservableCollection of Speaker

We will use an ObservableCollection<Speaker> that will be cleared and then loaded with Speaker objects. We use an ObservableCollection because it has built-in support to raise CollectionChanged events when we Add or Remove items from the collection. This means we don't call OnPropertyChanged when updating the collection.

  1. In SpeakersViewModel.cs declare an auto-property which we will initialize to an empty collection
public class SpeakersViewModel : INotifyPropertyChanged
{
    //...
    public ObservableCollection<Speaker> Speakers { get; set; } = new ObservableCollection<Speaker>();
    //...
}

7. Create GetSpeakers Method

We are ready to create a method named GetSpeakers which will retrieve the speaker data from the internet. We will first implement this with a simple HTTP request, and later update it to grab and sync the data from Azure!

  1. In SpeakersViewModel.cs, create a method named GetSpeakers with that returns async Task:
public class SpeakersViewModel : INotifyPropertyChanged
{
    //...
    private async Task GetSpeakers()
    {

    }
    //...
}
  1. In GetSpeakers, first ensure IsBusy is false. If it is true, return
private async Task GetSpeakers()
{
    if (IsBusy)
        return;
}
  1. In GetSpeakers, add some scaffolding for try/catch/finally blocks
    • Notice, that we toggle IsBusy to true and then false when we start to call to the server and when we finish.
private async Task GetSpeakers()
{
    if (IsBusy)
        return;

    try
    {
        IsBusy = true;

    }
    catch (Exception e)
    {

    }
    finally
    {
       IsBusy = false;
    }

}
  1. In the try block of GetSpeakers, create a new instance of HttpClient. - We will use HttpClient to get the json-ecoded data from the server
private async Task GetSpeakers()
{
    ...
    try
    {
        IsBusy = true;

        using(var client = new HttpClient())
        {
            var json = await client.GetStringAsync("https://demo8598876.mockable.io/speakers");
        }
    }
    ... 
}
  1. Inside of the using we just created, deserialize the json data and turn it into a list of Speakers using Json.NET:
private async Task GetSpeakers()
{
    ...
    try
    {
        IsBusy = true;

        using(var client = new HttpClient())
        {
            var json = await client.GetStringAsync("https://demo8598876.mockable.io/speakers");

            var items = JsonConvert.DeserializeObject<List<Speaker>>(json);
        }
    }
    ... 
}
  1. Inside of the using, clear the Speakers property and then add the new speaker data:
private async Task GetSpeakers()
{
    //...
    try
    {
        IsBusy = true;

        using(var client = new HttpClient())
        {
            var json = await client.GetStringAsync("https://demo8598876.mockable.io/speakers");

            var items = JsonConvert.DeserializeObject<List<Speaker>>(json);

            Speakers.Clear();

            foreach (var item in items)
                Speakers.Add(item);
        }
    }
    //...
}
  1. In GetSpeakers, add this code to the catch block to display a popup if the data retrieval fails:
private async Task GetSpeakers()
{
    //...
    catch(Exception e)
    {
        await Application.Current.MainPage.DisplayAlert("Error!", e.Message, "OK");
    }
    //...
}
  1. Ensure the completed code looks like this:
private async Task GetSpeakers()
{
    if (IsBusy)
        return;

    try
    {
        IsBusy = true;

        using(var client = new HttpClient())
        {
            //grab json from server
            var json = await client.GetStringAsync("https://demo8598876.mockable.io/speakers");

            //Deserialize json
            var items = JsonConvert.DeserializeObject<List<Speaker>>(json);

            //Load speakers into list
            Speakers.Clear();
            foreach (var item in items)
                Speakers.Add(item);
        }
    }
    catch (Exception e)
    {
        await Application.Current.MainPage.DisplayAlert("Error!", e.Message, "OK");
    }
    finally
    {
        IsBusy = false;
    }
}

Our main method for getting data is now complete!

8. Create GetSpeakers Command

Instead of invoking this method directly, we will expose it with a Command. A Command has an interface that knows what method to invoke and has an optional way of describing if the Command is enabled.

  1. In SpeakersViewModel.cs, create a new Command called GetSpeakersCommand:
public class SpeakersViewModel : INotifyPropertyChanged
{
    //...
    public Command GetSpeakersCommand { get; }
    //...
}
  1. Inside of the SpeakersViewModel constructor, create the GetSpeakersCommand and pass it two methods
    • One to invoke when the command is executed
    • Another that determines if the command is enabled. Both methods can be implemented as lambda expressions as shown below:
public class SpeakersViewModel : INotifyPropertyChanged
{
    //...
    public SpeakersViewModel()
    {
        GetSpeakersCommand = new Command(async () => await GetSpeakers(),() => !IsBusy);
    }
    //...
}

9. Build The SpeakersPage User Interface

It is now time to build the Xamarin.Forms user interface in View/SpeakersPage.xaml.

  1. In SpeakersPage.xaml, add a StackLayout between the ContentPage tags
    • By setting Spacing="0", we're requesting that no space is added between the contents of the StackLayout
<?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="DevDaysSpeakers.View.SpeakersPage"
             Title="Speakers">

    <StackLayout Spacing="0">

    </StackLayout>

</ContentPage>
  1. In SpeakersPage.xaml, add a Button that has a binding to GetSpeakersCommand
    • The command will be executed whenever the user taps the 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="DevDaysSpeakers.View.SpeakersPage"
             Title="Speakers">

    <StackLayout Spacing="0">

        <Button Text="Sync Speakers" Command="{Binding GetSpeakersCommand}"/>

    </StackLayout>

</ContentPage>
  1. In SpeakersPage.xaml, under the button, add an ActivityIndicator
    • The ActivityIndicator is a spinning indicator we'll use to let the user know we are retrieving the files in the background
    • The ActivityIndicator will be bound to IsBusy
<?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="DevDaysSpeakers.View.SpeakersPage"
             Title="Speakers">

    <StackLayout Spacing="0">

        <Button Text="Sync Speakers" Command="{Binding GetSpeakersCommand}"/>

        <ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}"/>

    </StackLayout>

</ContentPage>
  1. In SpeakersPage.xaml, add a ListView that binds to the Speakers collection to display all of the items.
    • We will use x:Name="ListViewSpeakers" so that we can access this XAML control from the C# code-behind
<?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="DevDaysSpeakers.View.SpeakersPage"
             Title="Speakers">

    <StackLayout Spacing="0">

        <Button Text="Sync Speakers" Command="{Binding GetSpeakersCommand}"/>

        <ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}"/>

        <ListView x:Name="ListViewSpeakers"
              ItemsSource="{Binding Speakers}"
              CachingStrategy="RecycleElement">
        <!--Add ItemTemplate Here-->
        </ListView>

    </StackLayout>

</ContentPage>
  1. In SpeakersPage.xaml, add a ItemTemplate to describe what each item looks like
    • Xamarin.Forms contains a few default Templates that we can use, and we will use the ImageCell that displays an image and two rows of text
<?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="DevDaysSpeakers.View.SpeakersPage"
             Title="Speakers">

    <StackLayout Spacing="0">

        <Button Text="Sync Speakers" Command="{Binding GetSpeakersCommand}"/>

        <ActivityIndicator IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}"/>

        <ListView
            x:Name="ListViewSpeakers"
            ItemsSource="{Binding Speakers}"
            CachingStrategy="RecycleElement">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ImageCell
                        Text="{Binding Name}"
                        Detail="{Binding Title}"
                        ImageSource="{Binding Avatar}"/>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>

    </StackLayout>

</ContentPage>

10. Connect SpeakersPage with SpeakersViewModel

Because we have bound some elements of the View to ViewModel properties, we have to tell the View with which ViewModel to bind. For this, we have to set the BindingContext to the SpeakersViewModel.

  1. In SpeakersPage.xaml.cs, create a field SpeakersViewModel vm, initialize vm and assign it to the BindingContext
public partial class SpeakersPage : ContentPage
{
    readonly SpeakersViewModel vm;

    public SpeakersPage()
    {
        InitializeComponent();

        // Create the view model and set as binding context
        vm = new SpeakersViewModel();
        BindingContext = vm;
    }
}

11. Run the App

  1. In Visual Studio, set the iOS, Android, or UWP project as the startup project

Startup project

  1. In Visual Studio, click "Start Debugging"
    • If you are having any trouble, see the Setup guides below for your runtime platform

iOS Setup

If you are on a Windows PC then you will need to be connected to a macOS build host with the Xamarin tools installed to run and debug the app.

If connected, you will see a Green connection status. Select iPhoneSimulator as your target, and then select a Simulator to debug on.

iOS Setup

Android Setup

Set the DevDaysSpeakers.Droid as the startup project and select a simulator. The first compile may take some additional time as Support Packages may need to be downloaded.

If you run into an issue building the project with an error such as:

aapt.exe exited with code or Unsupported major.minor version 52 then your Java JDK may not be setup correctly, or you have newer build tools installed then what is supported. See this technical bulletin for support: https://releases.xamarin.com/technical-bulletin-android-sdk-build-tools-24/

Additionally, see James' blog for visual reference: https://motzcod.es/post/149717060272/fix-for-unsupported-majorminor-version-520

If you are running into issues with Android support packages that can't be unzipped because of corruption please check: https://xamarinhelp.com/debugging-xamarin-android-build-and-deployment-failures/

Windows 10 Setup

Set the DevDaysSpeakers.UWP as the startup project and select debug to Local Machine.

12. Add Navigation

Now, let's add navigation to a second page that displays speaker details!

  1. In SpeakersPage.xaml.cs, under BindingContext = vm;, add an event to the ListViewSpeakers to get notified when an item is selected:
public partial class SpeakersPage : ContentPage
{
    readonly SpeakersViewModel vm;

    public SpeakersPage()
    {
        InitializeComponent();

        // Create the view model and set as binding context
        vm = new SpeakersViewModel();
        BindingContext = vm;

        ListViewSpeakers.ItemSelected += ListViewSpeakers_ItemSelected;
    }
}
  1. In SpeakersPage.xaml.cs, create a method called ListViewSpeakers_ItemSelected:
    • This code checks to see if the selected item is non-null and then use the built in Navigation API to push a new page and deselect the item.
private async void ListViewSpeakers_ItemSelected(object sender, SelectedItemChangedEventArgs e)
{
    var speaker = e.SelectedItem as Speaker;
    if (speaker == null)
        return;

    await Navigation.PushAsync(new DetailsPage(speaker));

    ListViewSpeakers.SelectedItem = null;
}

13. Create DetailsPage.xaml UI

Let's add UI to the DetailsPage. Similar to the SpeakersPage, we will use a StackLayout, but we will wrap it in a ScrollView. This allows the user to scroll if the page content is longer than the avaliable screen space.

  1. In DetailsPage.xaml, add a ScrollView and a StackLayout
<?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="DevDaysSpeakers.View.DetailsPage"
             Title="Details">
    <ScrollView Padding="10">
        <StackLayout Spacing="10">
            <!-- Detail controls here -->
        </StackLayout>
    </ScrollView>
</ContentPage>
  1. In DetailsPage.xaml, add controls and bindings for the properties in the Speaker class:
<?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="DevDaysSpeakers.View.DetailsPage"
             Title="Details">

    <ScrollView Padding="10">
        <StackLayout Spacing="10">
            <Image Source="{Binding Avatar}" HeightRequest="200" WidthRequest="200"/>

            <Label Text="{Binding Name}" FontSize="24"/>
            <Label Text="{Binding Title}" TextColor="Purple"/>
            <Label Text="{Binding Description}"/>
        </StackLayout>
    </ScrollView>
</ContentPage>
  1. In DetailsPage.xaml, add two buttons and give them names so we can access them in the code-behind.
    • We'll be adding click handlers to each 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="DevDaysSpeakers.View.DetailsPage"
             Title="Details">

    <ScrollView Padding="10">
        <StackLayout Spacing="10">
            <Image Source="{Binding Avatar}" HeightRequest="200" WidthRequest="200"/>

            <Label Text="{Binding Name}" FontSize="24"/>
            <Label Text="{Binding Title}" TextColor="Purple"/>
            <Label Text="{Binding Description}"/>

            <Button Text="Speak" x:Name="ButtonSpeak"/>
            <Button Text="Go to Website" x:Name="ButtonWebsite"/>
        </StackLayout>
    </ScrollView>
</ContentPage>

14. Add Text to Speech

If we open up DetailsPage.xaml.cs we can now add a few more click handlers. Let's start with ButtonSpeak, where we will use the Text To Speech Plugin to read back the speaker's description.

  1. In DetailsPage.xaml.cs, in the constructor, add a clicked handler below the BindingContext
public partial class DetailsPage : ContentPage
{
    readonly Speaker speaker;

    public DetailsPage(Speaker speaker)
    {
        InitializeComponent();

        //Set local instance of speaker and set BindingContext
        speaker = speaker;
        BindingContext = speaker;

        ButtonSpeak.Clicked += ButtonSpeak_Clicked;
    }
}
  1. In DetailsPage.xaml.cs, create the ButtonSpeak_Clicked method which will call the cross-platform API for text to speech
public partial class DetailsPage : ContentPage
{
    //...
    private async void ButtonSpeak_Clicked(object sender, EventArgs e)
    {
        await TextToSpeech.SpeakAsync(speaker.Description);
    }
}

15. Add Open Website Functionality

Xamarin.Forms includes many APIs for performing common tasks such as opening a URL in the default browser.

  1. In DetailsPage.xaml.cs, add a clicked handler for ButtonWebsite.Clicked:
public partial class DetailsPage : ContentPage
{
    //...
    public DetailsPage(Speaker speaker)
    {
        InitializeComponent();

        //Set local instance of speaker and set BindingContext
        this.speaker = speaker;
        BindingContext = this.speaker;

        ButtonSpeak.Clicked += ButtonSpeak_Clicked;
        ButtonWebsite.Clicked += ButtonWebsite_Clicked;
    }
    //...
}
  1. In DetailsPage.xaml.cs, create the ButtonSpeak_Clicked method which will use the static class Device to call the OpenUri method
public partial class DetailsPage : ContentPage
{
    //...
    private void ButtonWebsite_Clicked(object sender, EventArgs e)
    {
        if (speaker.Website.StartsWith("http"))
            Device.OpenUri(new Uri(speaker.Website));
    }
}

16. Compile & Run

Now, we should be all set to compile and run our application!

Azure Backend Walkthrough

Being able to grab data from a RESTful end point is great, but what about creating the back-end service? This is where Azure Mobile Apps comes in. Let's update our application to use an Azure Mobile Apps back-end.

1. Create Azure Mobile App

  1. Create a Free Azure account including a free $200 credit by navigating to this Azure Sign Up Page and creating an account

  2. In the Azure Portal, select the Create a resource button

  3. In New window, tap Mobile

  4. In New window, tap Mobile App

Create Resource

  1. In the Mobile App window, enter your App name

    • This is a unique name for the app that you will need when connecting your Xamarin.Forms client app to the hosted Azure Mobile App
    • You will need to choose a globally-unique name
    • I reccomend using yourlastnamespeakers
  2. In the Mobile App window, select your Subscription

    • Select a subscription or create a pay-as-you-go account (this service will not cost you anything).
  3. In the Mobile App window, create a new Resource Group

    • Select Create new and call it DevDaysSpeakers
    • A resource group is just a folder that holds multiple Azure services
  4. In the Mobile App window, select create new App Service plan/Location

  5. In the New App Service Plan window, enter a unique name

    • I reccommend yourlastnamespeakersserver
  6. In the New App Service Plan window, select a location (typically you would choose a location close to your customers)

  7. In the New App Service Plan window, select Pricing tier

  8. In the Pricing Tier window, select Dev/Test

  9. In the Pricing Tier window, select Free

  10. In the Pricing Tier window, select Apply

  11. In the New App Service Plan window, select OK

  12. In the Mobile App window, check Pin to dashboard

  13. In the Mobile App window, click Create

Create Mobile App

After clicking Create, it will take Azure about 3-5 minutes to create the new service, so let's head back to the code!

2. Update AzureService.cs

We will use the Azure Mobile Apps SDK to connect our mobile app to our Azure back-end with just a few lines of code.

  1. In AzureService.cs, add your url to the Initialize method:
var appUrl = "https://YOUR-APP-NAME-HERE.azurewebsites.net";

The logic in the Initialize method will setup our database and create our IMobileServiceSyncTable<Speaker> table that we can use to retrieve speaker data from the Azure Mobile App. There are two methods that we need to fill in to get and sync data from the server.

  1. In AzureService.cs, update the GetSpeakers method to initialize, sync, and query the table for items using LINQ queries to order the results:
public async Task<IEnumerable<Speaker>> GetSpeakers()
{
    await Initialize();
    await SyncSpeakers();
    return await table.OrderBy(s => s.Name).ToEnumerableAsync();   
}
  1. In AzureService.cs, update the SyncSpeakers method to sync the local database our in our app with our remote database in Azure:
public async Task SyncSpeakers()
{
    try
    {
        await Client.SyncContext.PushAsync();
        await table.PullAsync("allSpeakers", table.CreateQuery());
    }
    catch (Exception ex)
    {
        Debug.WriteLine("Unable to sync speakers, that is alright as we have offline capabilities: " + ex);
    }
}

That is it for our Azure code! Just a few lines, and we are ready to pull the data from Azure.

3. Update SpeakersViewModel.cs

  1. In SpeakersViewModel.cs, update GetSpeakers to use the Azure Service by amending the code in the try block:
private async Task GetSpeakers()
{
    //...
    try
    {
        IsBusy = true;

        var service = DependencyService.Get<AzureService>();
        var items = await service.GetSpeakers();

        Speakers.Clear();
        foreach (var item in items)
            Speakers.Add(item);
    }
    //...
}

Now, we have implemented the code we need in our app! Amazing isn't it? The AzureService object will automatically handle all communication with your Azure back-end for you, do online/offline synchronization so your app works even when it's not connected.

3. Populate Azure Database

Let's head back to the Azure Portal and populate the database!

  1. In the Azure Portal Dashboard, click on the Mobile App tile for the Azure Mobile App we created earlier.

Select Azure Mobile App

  1. On the left-hand menu, select Quickstart

  2. In the new window, select Xamarin.Forms

Xamarin Forms Quick Start

  1. In the Quick Start menu, select the box below Connect a database
  2. In the Data Connections window, select + Add
  3. In the Add data connection window, select the SQL Database box
  4. In the Database window, select Create a new database

Create Database

  1. In the SQL Database window, enter a name
    • The name must be unique
    • I recommend using LastnameSpeakersDatabase
  2. In the SQL Database window, select Target Server Configure required settings
  3. In the Server window, select Create a new server
  4. In the New server window, enter a Server name
    • The server name must be unique and all lower-case
    • I recommend using lastnamespeakerserver
  5. In the New server window, create a Server admin login
    • This will be your username for accessing the database remotely (which we won't be doing in this lab)
  6. In the New server window, create a Password
    • This will be your password for accessing the database remotely (which we won't be doing in this lab)
  7. In the New server window, Confirm Password
  8. In the New server window, select a Location
    • This is the physical location where your server will be located
    • I recommend selecting a location that is closest to your users
  9. In the New server window, select Select

Configure Database Server

  1. In the SQL Database window, select Pricing Tier
  2. In the Configure window, select Free
  3. In the Configure window, select Apply

Database Pricing Tier

  1. In the SQL Database window, select Select

Select SQL Database

  1. In the Add data connection window, select Connection String
  2. In the Connection string window, select OK, leaving the default value
  3. In the Add data connection window, select OK

Connection String

  1. Standby while Azure creates the Data Connection
    • This may take 3-5 minutes

Data Connection Create

Data Connection Completed

Our database is now created! Let's populate it with some data!

4. Populate Database with Data

  1. In the Azure Portal Dashboard, click on the Mobile App

Select Azure Mobile App

  1. In the Mobile App menu, enter easy into the search bar
  2. In the Mobile App menu, select Easy tables

Easy Tables

  1. In the Easy tables window, select Click here to continue

  2. In the new Easy tables window, check the box I acknowledge that this will overwrite all site contents.

  3. In the new Easy tables window, select Create TodoItem table

    • Ignore that it says "TodoItem Table"; selecting Create will create an empty table Initialize Easy Tables
  4. In the Easy tables window, select Add from CSV

Add From CSV

  1. In the Add from CSV window, select the Folder Icon
  2. In the file browser, locate and select the Speakers.csv file in the HandsOnLabs folder
  3. In the Add from CSV window, after uploading the CSV file, select the blank white button at the bottom
    • This is the save button; it's blank because of a bug
    • Note: If you get an error while uploading the Speaker.CSV file, it may be a bug that has been resolved. To workaround this, go to the "Application settings" under the "Settings" section and scroll to "App Settings". Change the value for MobileAppsManagement_EXTENSION_VERSION to 1.0.367 and save the changes. Now retry the "Add from CSV" process again

Upload CSV

application settings fix

  1. Re-run your application and get data from Azure!