Page 44 - MSDN Magazine, June 2017
P. 44

Client.LoginAsync method. LoginAsync takes two arguments: the context in which the authentication UI must be presented and the authentication provider via the MobileServiceAuthentication- Provider enumeration. It returns an object of type MobileService- User, which contains information about the authenticated user. In Xamarin.Forms, the code that authenticates the user can’t be shared in the PCL because iOS and Android manage UI contexts differently. The problem can be solved using the dependency ser- vice pattern, therefore adding to the PCL an interface that provides an abstract login method definition, and platform-specific imple- mentations of the interface. In the PCL project, add a new folder called Authentication and an interface called IAuthentication.cs that looks like the following:
using Microsoft.WindowsAzure.MobileServices; using System.Threading.Tasks;
namespace MyBookshelf.Authentication {
public interface IAuthentication {
Task<MobileServiceUser> LoginAsync(MobileServiceClient client, MobileServiceAuthenticationProvider provider);
} }
This custom definition of LoginAsync takes an instance of the MobileServiceClient class that’s passed by a View Model and that will be used to invoke its LoginAsync method from the platform-specific projects. Add a file called Authentication.cs to both the Android and iOS projects, then look at Figure 8 and Figure 9, which show the Android and iOS implementations, respectively.
With this approach, each platform-specific project can invoke LoginAsync passing the proper execution context.
In Xamarin.Forms, the code that authenticates the user can’t be shared in the PCL because iOS and Android manage UI contexts differently.
Implementing Data Access with
the Azure Mobile Client SDK
The MobileServiceClient class also provides everything you need to work with records in a table. You first obtain a reference to a table with the GetTable method, then with methods such as ToEnu- merableAync, InsertAsync, UpdateAsync and DeleteAsync, you can query, insert, update and delete records, respectively. These are all generic methods, so you can write a data access layer that can be reused to work with any object that derives from TableBase. Having said that, in the PCL project, add a DataAccess folder and a file called DataManager.cs inside. Before writing the DataManager class, add the following code to the App.xaml.cs file, so that a vari- able of type DataManager is available at the app level:
internal static DataManager DataManager; public App()
{
InitializeComponent();
DataManager = new DataManager(Constants.BaseUrl); MainPage = new MyBookshelf.MainPage();
}
Figure 10 shows the code for the DataManager class.
In the SaveAsync method, the Id property is used to detect if an item is new or existing. If it’s new, a new GUID is generated and the item is inserted; otherwise, it’s updated. In LoadAsync, the UserId property is used to filter the list of items based on the current user. This is possible because of generics and generic constraints, which let both methods work with any object that derives from TableBase.
The ViewModel
A ViewModel class will be responsible for exposing a collection of books, commands that let you work with Book items and the login logic. Add a new file called BookViewModel.cs into a sub- folder called ViewModel in the PCL project, then write the code shown in Figure 11.
Figure 12 The UI for the Main Page
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:MyBookshelf" x:Class="MyBookshelf.MainPage">
<Grid BindingContext="{Binding}">
<Grid.RowDefinitions> <RowDefinition Height="40"/> <RowDefinition Height="30"/> <RowDefinition /> <RowDefinition Height="40" />
</Grid.RowDefinitions>
<Label Text="My Bookshelf" FontSize="Large" Margin="5"/>
<ActivityIndicator x:Name="Indicator1" IsRunning="{Binding IsBusy}" IsVisible="{Binding IsBusy}" Grid.Row="1"/>
<ListView HasUnevenRows="True" ItemsSource="{Binding Books}" x:Name="BooksListView"
Grid.Row="2" SelectedItem="{Binding SelectedBook}" >
<ListView.ItemTemplate> <DataTemplate>
<ViewCell> <ViewCell.View>
<Frame OutlineColor="Blue"> <Grid>
<Grid.RowDefinitions> <RowDefinition/> <RowDefinition/>
</Grid.RowDefinitions>
<Entry Placeholder="Title" Text="{Binding Title}"/> <Entry Placeholder="Author" Text="{Binding Author}"
Grid.Row="1"/> </Grid>
</Frame> </ViewCell.View>
</ViewCell> </DataTemplate>
</ListView.ItemTemplate> </ListView>
<StackLayout Grid.Row="3" Orientation="Horizontal" BindingContext="{Binding}">
<Button Text="Load" x:Name="LoadButton" Command="{Binding LoadBooks}"/> <Button Text="Save" x:Name="SaveButton" Command="{Binding SaveBooks}"/> <Button Text="Add" x:Name="AddButton" Command="{Binding AddNewBook}"/>
</StackLayout> </Grid>
</ContentPage>
40 msdn magazine
Xamarin



















































   42   43   44   45   46