Consuming authenticated APIs with Xamarin.Forms

Consuming authenticated APIs with Xamarin.Forms

In this post, I’m going to build a fully functional cross-platform mobile application that consumes an authenticated Web APIs (OAuth authentication).
It’s a personalised To-Do application that you need to enter your phone number then enter the verification code after receiving it via SMS to enter your To-Do list.

All code can be found in my Github repository.

Step 1: Create a new Project

Using your favourite IDE (I’m using Visual Studio for Mac), Create a new solution and in the Multiplatform section choose Blank Forms App and go through the wizard to choose your preferred project directory and targeted platforms. If you need to get familiar on what to fill out in the wizard you can check my previous post
Note: It’s preferred to name the project ToDo just so we can have the same namespace in case you would like to copy paste.😋

Step 2: Consume Authentication API endpoints

  1. I’m going to start with organising the project with folders, so I’ll start with a folder named Interfaces and add a new interface called IAuthenticationService

    using System;
    using System.Net;
    using System.Threading.Tasks;

    namespace ToDo.Interfaces
    {
        public interface IAuthenticationService
        {
            Task Register(string phoneNumber);

            Task<HttpStatusCode> AuthorizeUser(string phoneNumber, string verificationCode);
        }
    }

    As shown from the code above, am listing all the required methods that we’re going to implement later on. They’re two methods Register phone number and Authorize User.
    The first one is to tackle our Web API Registration endpoint to send SMS for the registered phone number with the verification code.
    As for the second one, it will take the phone number and the received verification code to send back the Access token to the consumer so it can be saved in a secure place and later on to be passed with any requests.

  2. Now to start working on the implementation, we will create a new folder named Services and then a new class called AuthenticationService.

    using System;
    using System.Diagnostics;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using System.Net;
    using ToDo.Interfaces;

    namespace ToDo
    {
        public class AuthenticationService : IAuthenticationService
        {
            HttpClient client;
            readonly Uri baseUri = new Uri(Constants.BaseURL);

            public AuthenticationService()
            {
                client = new HttpClient();
                client.MaxResponseContentBufferSize = 256000;
            }

            public async Task Register(string phoneNumber)
            {
                string purgedPhoneNumber = phoneNumber;

                var uri = new Uri(baseUri, api/account/register);

                try
                {
                    if (phoneNumber.Contains(+)) { purgedPhoneNumber = phoneNumber.Replace(+); }
                    var json = string.Concat({\”username\”, purgedPhoneNumber, });
                    var content = new StringContent(json, Encoding.UTF8, application/json);

                    var response = await client.PostAsync(uri, content);
                    if (response.IsSuccessStatusCode)
                    {
                        Debug.WriteLine(@”successfully sent.);
                    }

                }
                catch (Exception ex)
                {
                    Debug.WriteLine(@”ERROR {0}, ex.Message);
                }
            }

            public async Task<HttpStatusCode> AuthorizeUser(string phoneNumber, string verificationCode)
            {
                string purgedPhoneNumber = phoneNumber;
                var uri = new Uri(baseUri, token);

                if (phoneNumber.Contains(+)) { purgedPhoneNumber = phoneNumber.Replace(+); }
                var postBody = new Dictionary<stringstring>()
                    {
                        {username, purgedPhoneNumber},
                        {password, verificationCode},
                        {grant_typepassword}
                    };

                var content = new FormUrlEncodedContent(postBody);

                var response = await client.PostAsync(uri, content);
                if (response.IsSuccessStatusCode)
                {
                    //var storeService = DependencyService.Get<IUserDetailsStore>();
                    var result = await response.Content.ReadAsStringAsync();
                    var jsonData = (JObject)JsonConvert.DeserializeObject(result);

                    var token = jsonData[access_token].Value<string>();
                    //Token should be saved in key chain instead of singleton class
                    //But for demo purposes, ill put it here
                    AccountDetailsStore.Instance.Token = token;
                    //storeService.SaveCredentials(phoneNumber, token);
                }
                return response.StatusCode;
            }
        }
    }

    As shown from the code above, we started our implementation with a constructor to initialize the Http client also we defined properties (the Http client and base URI that is going to be used throughout the class).

    So to start with the first method Register, firstly we do some purging for the parameterized input to remove the + sign if it exists, and prepare the post body which we send username: (the purged number) and then do the post request by passing the full URI and content.

    As for the second method AuthorizeUser, we do the same purging but we send different post body since we received the verification code and we want to get the access token in return.
    So the post body will be:

            {username, purgedPhoneNumber},
            {password, verificationCode},
            {grant_typepassword}

    Afterwards, when we check if the response is 200 (Ok), we need to save the access token in a safe, encrypted place. Now in our case, I made a singleton class to save the access token just for demo purposes but the ideal case should be done using this approach (This going to be covered in step 4 below).

    Note: These methods are marked as async methods and you need to add Newtonsoft package in order to use any JSON related code on the above sample.

  3. As noticed from the above code, am using a static class called Constants to read any static string from it. For now, I just have BaseURL constant in it.

    using System;
    namespace ToDo
    {
        public static class Constants
        {
            public static string BaseURL = https://bookmarkerapp.azurewebsites.net/;
        }
    }

  4. As for the Singleton class we’ve talked about saving the access token in memory, we will create a new folder called Helpers and a new class called AccountDetailsStore.

    using System;
    namespace ToDo
    {
        public sealed class AccountDetailsStore
        {
            private static readonly AccountDetailsStore instance = new AccountDetailsStore();

            private AccountDetailsStore() { }

            public static AccountDetailsStore Instance
            {
                get
                {
                    return instance;
                }
            }

            public string PhoneNumber { getset; }
            public string Token { getset; }
        }
    }

  5. The last step in this phase is to create the Authentication manager, so we’re going to create a new folder called Repositories and then a new class called AuthenticationRepository to call the methods in the interface (we can call any other implementation since we’re doing Dependency Injection).

    using System;
    using System.Threading.Tasks;
    using ToDo.Interfaces;

    namespace ToDo
    {
        public class AuthenticationRepository
        {
            IAuthenticationService authenticationService;

            public AuthenticationRepository(IAuthenticationService service)
            {
                authenticationService = service;
            }

            public Task RegisterAccount(string phoneNumber)
            {
                return authenticationService.Register(phoneNumber);
            }

            public Task<System.Net.HttpStatusCode> AutherizeAccount(string phoneNumber, string verificationCode)
            {
                return authenticationService.AuthorizeUser(phoneNumber, verificationCode);
            }
        }
    }

Step 3: Create Sign-in & Verification pages

In this step, we’re going to build two pages with code sharing of 100%, Sign-in page and verification page using XAML and C#.
To get started we create a new folder called Pages

  1. Sign-in page:
    Add a new ContentPage XAML by right click on the pages folder Add – New File… and the XAML form should look like 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=ToDo.SignIn>
        <ContentPage.Content>
            <StackLayout Orientation=Vertical VerticalOptions=CenterAndExpand Padding=20,0,20,0>
                <Label HorizontalOptions=Center HorizontalTextAlignment=Center Text=Select your country and enter your phone number in order to sign in>
                </Label>
                <Picker VerticalOptions=CenterAndExpand SelectedIndexChanged=CountryPicker_SelectedIndexChanged x:Name=countryPicker ItemDisplayBinding={Binding name} Title=Select a country…>
                </Picker>
                <Entry x:Name=phoneNumberEntry Keyboard=Telephone Placeholder=Enter your phone>
                </Entry>
                <Button Text=Sign in x:Name=signInButton>
                </Button>
                <ActivityIndicator x:Name=pageActivityIndicator>
                </ActivityIndicator>
                <Label HorizontalOptions=Center HorizontalTextAlignment=Start Text=You will receive an SMS with verification code.>
                </Label>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

    In this XAML, we’re adding a Stack Layout inside Content Page, if you’re familiar with Content page you probably know it only takes single view so we usually insert a container such as Stack layout or scroll view.
    In this Stack layout, I’m adding controls in a vertical order and each control is centralised in the middle. As you can also see that I’ve added some properties for the stack layout like the padding to add some spaces around it.
    Now in stack layout from top to bottom, there is an informative label for the users, a picker to select a country of their phone number (Which I talk more about soon), an entry control where the user can write their phone number, the sign in button, an activity indicator to show that there is a process happening at the moment and finally anther informative label.

    No for the C# code behind:

    using System;
    using System.Collections.Generic;
    using Xamarin.Forms;
    using Newtonsoft.Json;
    using System.IO;
    using System.Reflection;
    using System.Linq;

    namespace ToDo
    {
        public partial class SignIn : ContentPage
        {
            AuthenticationRepository autheticationRepo = new AuthenticationRepository(new AuthenticationService());

            bool isLoading
            {
                set
                {
                    pageActivityIndicator.IsVisible = value;
                    pageActivityIndicator.IsRunning = value;
                    signInButton.IsVisible = !value;
                    this.IsBusy = value;
                }
            }

            public SignIn()
            {
                InitializeComponent();
                Title = Sign in;

                configureCountryPicker();
                configureSignInButton();
                pageActivityIndicator.BindingContext = this;
            }

            private void configureCountryPicker()
            {
                countryPicker.ItemsSource = getCountries();
                countryPicker.SelectedIndexChanged += CountryPicker_SelectedIndexChanged;
            }

            private void configureSignInButton()
            {
                signInButton.Clicked += SignInButton_Clicked;
            }

            private List<Models.CountryCode> getCountries()
            {
                var assembly = typeof(SignIn).GetTypeInfo().Assembly;
                Stream stream = assembly.GetManifestResourceStream(ToDo.Data.Countries.json);

                List<Models.CountryCode> countryCodes;

                using (var reader = new System.IO.StreamReader(stream))
                {
                    var json = reader.ReadToEnd();
                    countryCodes = JsonConvert.DeserializeObject<List<Models.CountryCode>>(json);
                }
                return countryCodes;
            }

            private bool validateForm()
            {
                if (countryPicker.SelectedIndex == –1return false;
                if (string.IsNullOrWhiteSpace(phoneNumberEntry.Text)) return false;
                return true;
            }

            void CountryPicker_SelectedIndexChanged(object sender, EventArgs e)
            {
                if (countryPicker.SelectedIndex == –1) { return; }
                var selectCountry = (Models.CountryCode)countryPicker.SelectedItem;
                phoneNumberEntry.Text = selectCountry.dial_code;
            }

            async void SignInButton_Clicked(object sender, EventArgs e)
            {
                if (!validateForm()) { await DisplayAlert(ValidationPlease fill missing field(s)Ok); return; };
                isLoading = true;
                var phoneNumber = phoneNumberEntry.Text.Trim();
                await autheticationRepo.RegisterAccount(phoneNumber);
                await Navigation.PushAsync(new VerificationPage(phoneNumber));
                isLoading = false;
            }
        }
    }

    This is a partial class SignIn and a child class of ContentPage.
    In the constructor, We’re doing the setup for the page: the title, configuring the country picker, configuring the sign in button and assigning the page activity indicator contexts to self.
    In the configureCountryPicker(), We’re assigning the items data source for this picker by reading a country list JSON file, also in this function, we’re assigning the event method handler when selected index changed.
    As for the configureSignInButton(), we’re also assigning the event method handler when the button is clicked.
    In getCountries() method, we’re reading the JSON file which can be found in here. To add this JSON file, create a new project folder named Data and right click then add files… and choose the JSON downloaded from the above link. Make sure to mark it as embedded resource afterwards.
    It’s important to mention the server call that we do when users click (tap) on the sign in button, we just call the method from the repository AutherizeAccount found in autheticationRepo initialized in the property at the top.
    Then add a new folder and name it Models, to add a POCO class named CountryCode, just to bind it with the results of reading the JSON file.

    using System;
    namespace ToDo.Models
    {
        public class CountryCode
        {
            public string name { getset; }
            public string dial_code { getset; }
            public string code { getset; }
        }
    }

  2. Verification Page:
    This page is where users enter the verification code received via SMS to be redirected to the To-Do list.
    Add a new ContentPage XAML by right click on the pages folder Add – New File… the XAML form should look like 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=ToDo.VerificationPage>
        <ContentPage.Content>
            <StackLayout Orientation=Vertical VerticalOptions=CenterAndExpand Padding=20,0,20,0>
                <Label Text=Enter verification code>
                </Label>
                <Entry Keyboard=Numeric x:Name=verificationEntry Placeholder=e.g. 1234>
                </Entry>
                <Button x:Name=signInButton Text=Sign in>
                </Button>
                <ActivityIndicator x:Name=pageActivityIndicator>
                </ActivityIndicator>
            </StackLayout>
        </ContentPage.Content>
    </ContentPage>

    This page is simpler than the one we added previously, just a stack layout inside a content page with simple controls to let users add their verification code.
    Note the x:Name is like “id” property in ASP.Net web forms world, we can access this control from the server side because of this property.
    And below is the C# code for this page:

    using System;
    using System.Net;

    using Xamarin.Forms;

    namespace ToDo
    {
        public partial class VerificationPage : ContentPage
        {
            AuthenticationRepository autheticationRepo = new AuthenticationRepository(new AuthenticationService());
            string phoneNumber;

            bool isLoading
            {
                set
                {
                    pageActivityIndicator.IsVisible = value;
                    pageActivityIndicator.IsRunning = value;
                    signInButton.IsVisible = !value;
                    this.IsBusy = value;
                }
            }

            public VerificationPage(string phoneNumber)
            {
                InitializeComponent();

                this.phoneNumber = phoneNumber;
                Title = Verify yourself;
                configureSignInButton();
            }

            private void configureSignInButton()
            {
                signInButton.Clicked += SignInButton_Clicked;
            }

            async void SignInButton_Clicked(object sender, EventArgs e)
            {
                var verificationCode = verificationEntry.Text.Trim();
                isLoading = true;
                var isSuccess = await autheticationRepo.AutherizeAccount(phoneNumber, verificationCode);
                if (isSuccess == HttpStatusCode.OK)
                {
                    await Navigation.PushAsync(new MainPage());
                }
                else
                {
                    await DisplayAlert(Ops…Something went wrong, please try again laterOk);
                }
                isLoading = false;
            }
        }
    }

    The main functionality of this page is to call the AutherizeAccount and retrieve the access token to be coupled with any endpoint request later on (operation endpoints).

  3. This step is just to make sure that you change the main page of the app by changing one line in App.xaml.cs

    MainPage = new NavigationPage(new SignIn());

Step 4: Consume CRUD operations

Now to consume all the Create, Read, Update and Delete operations for the To-Do list, we’re going to do the same thing as previously, Create an interface for all the required methods and implement them in the service class and finally consume them in the Repository class.

  1. Let start with the interface, we shall name the interface with IToDoService (Surly inside Interfaces folder).

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Threading.Tasks;
    using ToDo.Models;

    namespace ToDo.Interfaces
    {
        public interface IToDoService
        {
            Task<List<ToDoItem>> GetToDoList();

            Task<HttpStatusCode> DeleteToDoItem(int itemId);

            Task<Uri> AddNewToDoItem(ToDoItem item);

            Task<ToDoItem> UpdateToDoItem(int id, ToDoItem item);
        }
    }

    As you can see from the code above, these are asynchronous methods some of them take id as integer and some take item DTO.
    So apparently we need to create this DTO which called ToDoItem, shall we?

    using System;
    namespace ToDo.Models
    {
        public class ToDoItem
        {
            public int Id { getset; }
            public string Name { getset; }
            public string Notes { getset; }
            public bool Done { getset; }
        }
    }

  2. Now we start with the implementation, create a new class named ToDoService inside the Services folder:

    using System;
    using System.Collections.Generic;
    using System.Net;
    using System.Net.Http;
    using System.Text;
    using System.Threading.Tasks;
    using Newtonsoft.Json;
    using ToDo.Interfaces;
    using ToDo.Models;
    using Xamarin.Forms;

    namespace ToDo
    {
        public class ToDoService : IToDoService
        {
            //I recommend to use 
            //https://docs.microsoft.com/en-us/aspnet/web-api/overview/advanced/calling-a-web-api-from-a-net-client

            HttpClient client;
            //IUserDetailsStore storeService;
            readonly string token;
            readonly Uri baseUri = new Uri(Constants.BaseURL);

            public ToDoService()
            {
                //storeService = DependencyService.Get<IUserDetailsStore>();
                token = AccountDetailsStore.Instance.Token;
                client = new HttpClient();
                client.MaxResponseContentBufferSize = 256000;
            }

            public async Task<HttpStatusCode> DeleteToDoItem(int id)
            {
                var uri = new Uri(baseUri, string.Format(api/todo/{0}, id));

                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Add(Authorizationstring.Format(Bearer {0}, token));

                var response = await client.DeleteAsync(uri);

                return response.StatusCode;
            }

            public async Task<Uri> AddNewToDoItem(ToDoItem item)
            {
                var uri = new Uri(baseUri, api/todo/);

                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Add(Authorizationstring.Format(Bearer {0}, token));

                var json = JsonConvert.SerializeObject(item);
                var content = new StringContent(json, Encoding.UTF8, application/json);
                var response = await client.PostAsync(uri, content);

                response.EnsureSuccessStatusCode();

                // Return   the URI of the created resource.
                return response.Headers.Location;
            }

            public async Task<ToDoItem> UpdateToDoItem(int id, ToDoItem item)
            {
                var uri = new Uri(baseUri, string.Format(api/todo/{0}, id));

                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Add(Authorizationstring.Format(Bearer {0}, token));

                var json = JsonConvert.SerializeObject(item);
                var content = new StringContent(json, Encoding.UTF8, application/json);
                var response = await client.PutAsync(uri, content);

                // Deserialize the updated product from the response body.
                var responseContent = await response.Content.ReadAsStringAsync();
                return JsonConvert.DeserializeObject<ToDoItem>(responseContent);
            }

            public async Task<List<ToDoItem>> GetToDoList()
            {
                var uri = new Uri(baseUri, api/todo/);

                client.DefaultRequestHeaders.Clear();
                client.DefaultRequestHeaders.Add(Authorizationstring.Format(Bearer {0}, token));

                var response = await client.GetAsync(uri);

                if (response.IsSuccessStatusCode)
                {
                    var content = await response.Content.ReadAsStringAsync();
                    return JsonConvert.DeserializeObject<List<ToDoItem>>(content);
                }
                return new List<ToDoItem>();
            }
        }
    }

    So in this implementation, we have few properties the http client, a string token and base URI. In the constructor, we’re initializing them and filling out the access token saved in the singleton class which was filled genuinely in the Authentication service.
    Now in each method, we’re doing separate API calls GET, POST, DELETE and PUT. As you can see we’re passing the Authorization header with Bearer accessToken.
    Also making sure the content of each request is UTF8 encoded.

  3. Let’s do the Repository ToDoRepository:

    using System;
    using System.Net;
    using System.Threading.Tasks;
    using System.Collections.Generic;
    using ToDo.Interfaces;
    using ToDo.Models;

    namespace ToDo
    {
        public class ToDoRepository
        {
            readonly IToDoService todoService;

            public Task<List<ToDoItem>> GetToDoList()
            {
                return todoService.GetToDoList();
            }

            public ToDoRepository(IToDoService todoService)
            {
                this.todoService = todoService;
            }

            public Task<HttpStatusCode> DeleteToDoItem(int itemId)
            {
                return todoService.DeleteToDoItem(itemId);
            }

            public Task<Uri> AddNewToDoItem(ToDoItem item)
            {
                return todoService.AddNewToDoItem(item);
            }

            public Task<ToDoItem> UpdateToDoItem(int id, ToDoItem item)
            {
                return todoService.UpdateToDoItem(id, item);
            }
        }
    }

Step5: ToDo list and Add/Edit pages

By right clicking on the Pages folder then add Forms ContentPage XAML and name it MainPage with the following 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=ToDo.MainPage>
    <ContentPage.Content>
        <ListView x:Name=todoListView ItemSelected=todoListView_ItemSelected>
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.ContextActions>
                            <MenuItem Text=Delete IsDestructive=True Clicked=OnTaskDelete CommandParameter={Binding Id} />
                        </ViewCell.ContextActions>
                        <StackLayout Padding=20,0,0,0 HorizontalOptions=StartAndExpand Orientation=Horizontal>
                            <Label Text={Binding Name} VerticalTextAlignment=Center />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.Footer>
                <Button x:Name=AddTaskButton Text=Add task></Button>
            </ListView.Footer>
        </ListView>
    </ContentPage.Content>
</ContentPage>

This page looks like a UITableView in the iOS world and ListView in Android world, we’re defining the cell template here to be a stack layout and have a label in it which will contain the to-do item title. Having stack layout as a template will give us the capability to add more controls later on.

Also, you will notice that we have defined the menu item, which is the delete button.
The delete button will behave according to the platform, press and hold on Android and swipe the cell to the left to see the delete button in iOS and by having command parameter we’re going to pass the ID to the function which is in our case OnTaskDelete.


If you notice, we have “Add task” button at the footer of this list view to redirect users to the Add/Edit page and also by having this button at the footer we’re preventing list view from having extra empty cells. Definitely, it’s going to look lame if we have extra empty cells.
now going to C# code:

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using ToDo.Models;
using Xamarin.Forms;

namespace ToDo
{
    public partial class MainPage : ContentPage
    {
        ToDoRepository todoRepo = new ToDoRepository(new ToDoService());

        public MainPage()
        {
            InitializeComponent();

            configurePage();
        }

        private void configurePage()
        {
            Title = To do list;
            AddTaskButton.Clicked += AddTaskButton_Clicked;
            NavigationPage.SetHasBackButton(thisfalse);
        }

        protected override void OnAppearing()
        {
            base.OnAppearing();
            var _ = configureTodoList();
        }

        private async Task configureTodoList()
        {
            todoListView.ItemsSource = await todoRepo.GetToDoList();
        }

        void AddTaskButton_Clicked(object sender, EventArgs e)
        {
            Navigation.PushAsync(new ItemDetailsPage(new ToDoItem()));
        }

        void todoListView_ItemSelected(object sender, Xamarin.Forms.SelectedItemChangedEventArgs e)
        {
            var todoItem = e.SelectedItem as ToDoItem;
            var itemDetailsPage = new ItemDetailsPage(todoItem)
            {
                BindingContext = todoItem
            };
            Navigation.PushAsync(itemDetailsPage);
        }

        public async void OnTaskDelete(object sender, EventArgs e)
        {
            var menuItem = ((MenuItem)sender);
            var taskId = (Int32)menuItem.CommandParameter;
            var isConfirmed = await DisplayAlert(Delete ConfirmationAre you sure you want to delete this task?ConfirmCancel);

            if (isConfirmed)
            {
                await todoRepo.DeleteToDoItem(taskId);
                await configureTodoList();
            }
        }
    }
}

Again, As I usually do, I start explaining the constructor. Oh, there is nothing abnormal here just removing the back button to not get back to the verification page nor sign in one. also, we’re assigning the event handler for the add task button.

Finally, Add/Edit page named ItemDetailsPage:

<?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=ToDo.ItemDetailsPage>
    <ContentPage.Content>
        <StackLayout Orientation=Vertical VerticalOptions=StartAndExpand Padding=20,0,20,0>
            <Label Text=Name>
            </Label>
            <Entry x:Name=nameEntry Keyboard=Default Text={Binding Path=Name} Placeholder=task name>
            </Entry>
            <Label Text=Notes>
            </Label>
            <Editor x:Name=notesEditor HeightRequest=90 Keyboard=Default Text={Binding Path=Notes}>
            </Editor>
            <Label Text=Done>
            </Label>
            <Switch x:Name=doneSwitch IsToggled={Binding Path=Done}>
            </Switch>
            <Button Text=Save x:Name=saveItemButton VerticalOptions=CenterAndExpand Clicked=SaveItemButton_Clicked>
            </Button>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Regular content page with controls in it to represent a form for adding or editing tasks.
C# code:

using System;
using System.Collections.Generic;
using ToDo.Models;
using Xamarin.Forms;

namespace ToDo
{
    public partial class ItemDetailsPage : ContentPage
    {
        ToDoItem toDoItem;
        ToDoRepository toDoRepo = new ToDoRepository(new ToDoService());

        public ItemDetailsPage(ToDoItem item)
        {
            InitializeComponent();
            this.toDoItem = item;
            Title = Details;
        }

        async void SaveItemButton_Clicked(object sender, System.EventArgs e)
        {
            toDoItem.Name = nameEntry.Text.Trim();
            toDoItem.Notes = notesEditor.Text.Trim();
            toDoItem.Done = doneSwitch.IsToggled;

            if (toDoItem.Id == 0)
            {
                await toDoRepo.AddNewToDoItem(toDoItem);
            }
            else
            {
                await toDoRepo.UpdateToDoItem(toDoItem.Id, toDoItem);
            }
            await Navigation.PopAsync(true);
        }
    }
}

Create main screen, Master-Detail Page (Part 3)

In this part, I’m going to create a main screen for the app and it’s going to be skeleton as some kind of blue·print so we can fill these pages later on with controls and contents.
First of all, you should ask yourself a question:

What is Master-Details page?

According to xamarin.com, MasterDetailPage is a page that manages two related pages of information – a master page that presents items, and a detail page that presents details about items on the master page.
it looks like as shown below:

master-detail

So, what am willing to do is to have the main screen where I can show all the promoted products and any news or trends in the detail page and on the master page i will list all the menu items, and so far am adding these:

  • Home
  • Products
  • Contact us

In summary, the list pages will be like this:

  • MainPage.xaml: MasterDetailPage, is the main container which has the menu (Hamburger menu) and contains Master and Detail properties that are both of type Page and used to get and set the master and detail pages respectively.
  • MasterPage.xaml: page where we will list all the menu items in, and once a user taps on one of these menu items, we will load this page in the detail page.
  • HomePage.xaml: page where I’ll show all the promoted products and any news or trends as mentioned above – this page will be loaded initially in MainPage.
  • ProductsPage.xaml: page where we will show products to be purchased, might contain search functionality and some filtrations.
  • ContactUsPage.xaml: Regular contact us page.

Before we get started on making pages, I would like to make a new folder name it Pages and after that, we shall create page by page (in the part, we will cover main, master and home pages).

MainPage

So on the Pages folder, we right click -> Add -> New file… and then from the forms menu choose Forms ContentPage Xaml, let’s name it MainPage.xaml
In this page, you can write the following XAML code:

<?xml version=1.0 encoding=UTF8?>
<MasterDetailPage
        xmlns=http://xamarin.com/schemas/2014/forms
        xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml
        x:Class=PuzzlersJordan.MainPage
        xmlns:local=clrnamespace:PuzzlersJordan;assembly=PuzzlersJordan
        Title=Main>
    <MasterDetailPage.Master>
        <local:MasterPage x:Name=masterPage>
        </local:MasterPage>
    </MasterDetailPage.Master>
    <MasterDetailPage.Detail>
        <NavigationPage>
            <x:Arguments>
                <local:HomePage />
            </x:Arguments>
        </NavigationPage>
    </MasterDetailPage.Detail>
</MasterDetailPage>

you can find in this XAML code that there is unusual declaration shown in below line:

xmlns:local=clrnamespace:PuzzlersJordan;assembly=PuzzlersJordan

This line is a reference declaration to the current assembly in order to reference any class found in the assembly, to reference any class you should use the local keyword as shown below:

  <local:MasterPage x:Name=masterPage>
  </local:MasterPage>

Or in:

<local:HomePage />

So to set MasterDetailPage.Master property we assign MasterPage to it and we gave it a name which is masterPage (so we can call it from the code behind).
On the other hand, for the detail property, we set a navigation page with a root page Home page.

So for the code behind, open MainPage.xaml.cs and the code should look like below:

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace PuzzlersJordan
{
    public partial class MainPage : MasterDetailPage
    {
        public MainPage()
        {
            InitializeComponent();
            masterPage.masterMenuList.ItemSelected += OnItemSelected;
        }

        void OnItemSelected(object sender, SelectedItemChangedEventArgs e)
        {
            var item = e.SelectedItem as MasterPageItem;
            if (item != null)
            {
                Detail = new NavigationPage((Page)Activator.CreateInstance(item.TargetType));
                masterPage.masterMenuList.SelectedItem = null;
                IsPresented = false;
            }
        }
    }
}

In the constructor, we accessed masterPage and then an instance of the masterMenuList (which is a listView that we will talk about later) to assign an event handler whenever a user taps on any of the menu items (item get selected).
So what we’re going to do is when the user taps on the menu item we will take the corresponding page and load it on the detail property and set selectedItem to null so it won’t be highlighted.

MasterPage

It’s the left menu that has all the menu items, UI wise it’s just a contentPage that has a simple StackLayout with some decoration properties shown below:

<?xml version=1.0 encoding=UTF8?>
<ContentPage xmlns=http://xamarin.com/schemas/2014/forms xmlns:x=http://schemas.microsoft.com/winfx/2009/xaml x:Class=PuzzlersJordan.MasterPage Padding=0,40,0,0 Icon=Hamburger Title=Menu>
    <ContentPage.Content>
        <StackLayout VerticalOptions=FillAndExpand>
            <ListView x:Name=MenuListView VerticalOptions=FillAndExpand SeparatorVisibility=None>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextCell Text={Binding Title} TextColor=#a9d300 />
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

Let’s talk a little bit about the code above:

  • Content page with padding of 40 points from the top and a must have title.
  • Set the icon of Hamburger which comes for free with android but we have to set it manually on iOS (follow this tutorial in order to do that).
  • We have ListView control with a data template to bind data from item class.

As for the code behind:

using System;
using System.Collections.Generic;

using Xamarin.Forms;

namespace PuzzlersJordan
{
    public class MasterPageItem
    {
        public string Title { get; set;}
        public Type TargetType { get; set; }

    }

    public partial class MasterPage : ContentPage
    {

        public ListView masterMenuList
        {
            get
            {
                return MenuListView;
            }
        }

        public MasterPage()
        {
            InitializeComponent();
            var masterPageItems = new List<MasterPageItem>();

            masterPageItems.Add(new MasterPageItem
            {
                Title = Home,
                TargetType = typeof(HomePage)
            });

            masterPageItems.Add(new MasterPageItem
            {
                Title = Products,
                TargetType = typeof(ProductsPage)
            });

            masterPageItems.Add(new MasterPageItem
            {
                Title = Contact us,
                TargetType = typeof(ContactUsPage)
            });

            MenuListView.ItemsSource = masterPageItems;
        }
    }
}

I declared a simple class (MasterPageItem) with two properties Title and TargetType. On the constructor, filled out a list of menu items in the new instance of a list of MasterPageItem and assigned it to the ItemSource.

HomePage

Just an empty content page that we will work on it later, but we need it here just to not break the detail page on MainPage.

Adding Splash screen (Part 2)

Adding Splash screen (Part 2)

The splash screen is very important to any mobile application it gets users attention from first sight.

What is Splash screen?

A splash screen is a graphical control element consisting of a window containing an image, a logo and the current version of the software. A splash screen usually appears while a game or program is launching.

Since Xamarin.Forms doesn’t support adding splash screen from one place like it does for pages, you need to go to each platform project – in our case iOS and Android – and add splash screen for each one.

iOS:

In our solution, you go to PuzzlersJordan.iOS project and follow this simple steps:

  1. In the Solution Explorer, double-click LaunchScreen.storyboard to open it for editing.
  2. Ensure that the Size Class is set to any:any and the View As is Generic.
    storyboard05.png
  3. Set the background colour of the main View by opening the properties panel – widget tab then background property.
    screen-shot-2017-02-20-at-11-36-24-pm
  4. Drag an Image View from the Toolbox into the design surface and set it at the centre of the screen.
    screen-shot-2017-02-20-at-11-48-12-pm
  5. Set the source of the Image (as an Image added to the project as an Asset Catalog) in the Property Explorer and reposition and size the image as required.
  6. Add the required constraints in order to keep image placed at the centre of the screen, constraints are:
    Vertical Alignment
    Horizontal Alignment
    screen-shot-2017-02-20-at-11-54-00-pm.png
  7. Save the changes to the Storyboard.

Am using this method because I have only the logo (not the whole images), In case you have a whole image you can follow these instructions provided by xamarinhelp.com:

  1. Create a splash screen image in the following sizes:
    320×480
    640×960
    640×1136
  2. Go to Properties > iOS Application > iPhone Launch Images and import the images. It will automatically add them to the Resources folder in your iOS Project.
    ios_splashscreen_settings
  3. Move down the properties page to add an image for iPad apps.
  4. If you are having issues with your images still displaying there are a few possible causes. The LaunchScreen.storyboard could be the issue. You can open it and correct it, or even try deleting it. Once you have done this, rebuild your application and reset your iOS Simulator or delete from your iPhone as iOS has a tendency to cache extensively in this area.

Android:

For Android, things are different. there are different ways to implement a splash screen. I have come across one of the easiest and quickest ways to do so.

All we need to do is we create a custom theme and apply it to an Activity that exhibits the splash screen. When the Activity is rendered, it loads the theme and applies the drawable resource (referenced by the theme) to the background of the activity. This approach avoids the need for creating a layout file.

Once the app has bootstrapped, the splash screen Activity starts the main Activity and removes itself from the application back-stack.

Follow along to make a fabulous splash screen for Android:

  1. Create a drawable resource for the splash screen to cater for the below resolutions (personally, I ask the designer to do so), this drawable is just the logo that we want to show in the center of the screen, name it ‘splash_logo’ since we’re going to refer to it later on:
    drawable-hdpi
    drawable-ldpi
    drawable-mdpi
    drawable-xhdpi
    drawable-xxhdpi
    drawable-xxxhdpi
    Note: It is necessary to use a bitmapped image (such as a PNG or JPG) for the image to display.
  2. In this step, we create two files:
    a. In order to reference colours in the following step, we need to create a new resource XML file inside values folder called colors.xml

    <?xml version=1.0 encoding=utf8?>
    <resources>
      <color name=splash_background>#A7CD38</color>
    </resources>

    b. To centre the splash screen image in the application, I’ll use a Layer List. The following snippet is an example of a drawable resource using a layer-list:

    <?xml version=1.0 encoding=utf8?>
    <layer-list xmlns:android=http://schemas.android.com/apk/res/android>
      <item>
        <color android:color=@color/splash_background/>
      </item>
      <item>
        <bitmap
            android:src=@drawable/splash_logo
            android:tileMode=disabled
            android:gravity=center/>
      </item>
    </layerlist>

    This layer-list will centre the splash screen image splash_logo.png on a background specified by the @color/splash_background resource as we created in step a.

  3. Create a custom theme for the splash screen Activity, edit (or add) the file values/styles.xml and create a new style element for the splash screen. A sample values/style.xml file is shown below with a style named splashscreen:

    <?xml version=1.0 encoding=UTF8?>
    <resources>
        <style name=splashscreen parent=MyTheme.Base>
            <item name=android:windowBackground>@drawable/splash_screen</item>
            <item name=android:windowNoTitle>true</item>
            <item name=android:windowIsTranslucent>false</item>
            <item name=android:windowIsFloating>false</item>
            <item name=android:backgroundDimEnabled>true</item>
            <item name=android:colorPrimaryDark>#85A42C</item>
        </style>


    </resources>

  4. We need a new Activity called SplashActivity to launch that has our splash image and performs any startup tasks. The following code is an example of a complete splash screen implementation:

    using Android.App;
    using Android.OS;
    using Android.Support.V7.App;

    namespace PuzzlersJordan.Droid
    {
        [Activity(Label = Puzzlers Jordan, Icon = @drawable/icon, Theme = @style/splashscreen, MainLauncher = true, NoHistory = true)]
        public class SplashActivity : AppCompatActivity
        {
            protected override void OnCreate(Bundle savedInstanceState)
            {
                base.OnCreate(savedInstanceState);
                this.StartActivity(typeof(MainActivity));
            }
        }
    }

    As noticed from the above implementation, we’re assigning splashscreen theme created previously to this activity and made sure to set this activity as the Main Launcher so when the app get launched it should trigger this activity at first.

    Also, note that we attributed this activity to have NoHistory set to true so it means that the activity will not leave a historical trace. It will not remain in the activity stack for the task so the user will not be able to return to it.

    Note: You most remove the MainLauncher attribute from MainActivity.

Let’s create a project, shall we? (Part 1)

Let’s create a project, shall we? (Part 1)

In order to get started, we need do the setup for our solution (the base block) and start from there.

Project Setup:

This is a trivial part, you need to launch your preferred IDE (as mentioned before am using Xamarin Studio) and follow these instructions:

  1. From the menu go to File, click New Solution. from the left panel under Multiplatform section choose App and from the middle panel choose Forms App with C# then press Next button.
    screen-shot-2017-02-22-at-7-56-05-pm
  2. On the second screen, Write the name of the app you’re intending to create in the App Name field (In my case the name will be PuzzlersJordan), and then write the Organization identifier.

    What is Organization identifier?

    It’s that identifier that is being used in your app to be distinguished among other apps, it comes with the form ‘com.yourcompanyname.productname’.
    For Android, it will be the package name and for iOS, it’s the bundle identifier.

    Next, make sure to check Android and iOS as Target Platforms and for the Shared Code choose ‘Use portable Class library’ and check XAML for user interface files.

    What is the difference between Shared Library and portable class library?

    To answer this question it will take me a whole blog post just to explain it. so instead I recommend reading this Xamarin Help blog post by Adam Pedley.

    screen-shot-2017-02-22-at-9-25-29-pm.png

  3. The last step, you need to specify the name of the project and solution, where should it be located on your machine and if you want to create a git repository for it.
  4. Press Create and you will be ready to develop the solution.

What are we going to build? (Part 0)

What are we going to build? (Part 0)

Previously, we talked about what is Xamarin, it’s pros/cons and Xamarin family members, It’s highly recommended to be familiar with Xamarin before kicking off with this series. if you haven’t checked it before you can click on this link.
In this series, we will be building up an application for a friend of mine, owner of Puzzlers Jordan in order to grow his business up and reach a better amount of customers/puzzle lovers.
At the moment of writing this post, the app hasn’t been created. so I’ll be building a simple functional mobile app with little to no complications for the two dominant platforms in the market (Android and iOS), I’ll be using Xamarin.Forms.
I made this decision after checking Xamarin’s site Is Xamarin.Forms right for your project? plus considering it as a challenge 😊

screen-shot-2017-02-20-at-9-17-51-pm

Finally, before we start we need to know what are the environments prior starting building the application:
This screenshot demonstrates windows and mac operating systems

screen-shot-2017-02-20-at-9-52-04-pm

So choose your preferred IDE and OS. As for me am going to use Xamarin Studio for MacOS as my IDE, feel free to follow along with any other IDE.

Before we start, note the below:

  • You have to be familiar with C# and little XAML.
  • Have a mac machine or at least connected to one since iOS platform is part of our solution.

Enjoy 🙂

Introduction to Xamarin

Introduction to Xamarin

At the time i’m writing this post, there are two popular platforms taking over the market, a two-horse race between iOS and Android. The two mobile operating systems combined for 98.4 percent worldwide market share in the fourth calendar quarter of 2015, compared to 96.4 percent in the year-ago quarter according to research firm Gartner.

For instance, when I want to check my Facebook or twitter account, I personally prefer checking it from their official mobile app rather than navigating to the site, yes believe it or not mobile applications are taking over the web world.

Cool, As a technology enthusiastic or even as a company that would like to promote itself  or a product/service in the market we have to follow this trend, but we have to play it smart, how?

Think about it, if a company would like to build an app for the three platforms: Android, iOS and Windows phone. the company has to hire resources/teams with knowledge of three programming languages: Java for Android, Objective-C or Swift for iOS and C# and XAML for Windows phone. this approach is called Siloed approach

screen-shot-2016-10-09-at-9-49-30-pm

Now following this approach they will end up with the following cons:

  • No code sharing between the three platforms.
  •  High maintenance level, since we have three platforms, resources or programming languages.
  • Expensive 💰💰.

On the other hand, we cannot deny how awesome the app going to look like, it’s because:

  • You get best of class performance wise.
  • Ability to access hardware easily.
  • Native user experience.

Some companies are frustrated by the high cost of this approach, so they follow anther approach which is Web-based app. You can reuse the code across different platforms by writing HTML, CSS and Javascript (could be an excellent idea if you came from web development background).

You can consider the benefits of going with this approach to be:

  • Write code once for all.
  • Saving money $$$.

What are the disadvantages of this approach?

  • Performance isn’t always perfect (Remember we’re running a web app).
  • it’s not always easy to access all native features of the platform.

Two of the most popular web-based frameworks are Cordova and Ionic

The good news! we’ve got 🎉 Xamarin 🎉 which tries to give us the best of the two approaches, Code sharing with C# and you end up getting a native app.

What is Xamarin?

It’s a fantastic tool that has done all the work to allow us to be able to write a mobile application in C# and run it on just about any mobile platform.

  • Native UI, native API access, and native performance
  • Anything you can do in Objective-C, Swift, or Java you can do in C# with Xamarin.
  • Ship cutting-edge apps with same-day support for new OS releases

Meet the Xamarin family

screen-shot-2016-10-09-at-11-14-28-pm

So what’s the difference between Xamarin.iOS, Xamarin.Android and Xamarin.Forms?

Xamarin.iOS and Xamarin.Android as from their names indicate, they’re the UI toolkits for building an app with the help of each platform’s APIs and the Mono .Net framework. if you choose to build an app using these two products you get the benefit of customising UI for each one but there is a trade-off is to have less code sharing.

On the other hand, if you choose to build an app with Xamarin.Forms you will write code only once and this code gets to be translated at runtime to each platform native, the good thing about this is you might get code sharing percentage up to 90%.

I’m confused, which product shall I choose to build my app?

Xamarin.Forms is best for:

  • Apps that require little platform-specific functionality.
  • Apps where code sharing is more important than custom UI. • Developers comfortable with XAML.

Xamarin.iOS & Xamarin.Android are best for:

  • Apps with interactions that require native behaviour.
  • Apps that use many platform-specific APIs.
  • Apps where custom UI is more important than code sharing.

Advantages of Xamarin:

  1. Leverage your .NET and C# knowledge
  2. Native user interface.
  3. Native performance.
  4. Code sharing.

Disadvantages of Xamarin (Xamarin.iOS and Xamarin.Android):

  1. Not a Shared UI platform:
    Following these two products will make you write more customised UI code for each platform but at the same time, you will get the opportunity to share 60% of the code as shown below.
    screen-shot-2016-10-11-at-9-03-32-pm
  2. Hardware requirements:
    If you would you like to run/compile your iOS app using Xamarin studio or visual studio, you must have a mac machine to compile it for you. you can get yourself a mac machine (like me), connect one on the same network that you’re using or you can rent a mac in the cloud such as MacinCloud services.

    You can find the option that suits you well by checking Xamarin.iOS requirement & installation.

  3. Minor learning curve:
    Sure there is a learning curve to know how are you going to deal with Xamarin.Android and Xamarin.iOS APIs, and even how are you going to build UI and so on.

Did someone say anything about IDEs?

Visual Studio:

xamarin2x-yuj5jk33

To get all the benefits such as Team explorer or Resharper using visual studio is the one for you.

 

Xamarin Studio:

ios-designer

If you’re a mac user, you can’t install visual studio on your machine that’s why Xamarin studio comes in hand. Xamarin studio is also available for PC users but personally, I prefer using Visual studio if am running a windows machine.

You can find all the installation instructions by checking this link.
Update (6/1/2017) Visual Studio for mac:

At Connect(); 16 in November, Microsoft is launching a preview of Visual Studio for Mac i couldn’t believe that i can use visual studio on my mac machine without the need for Bootcamp partition on my machine.
But no, after reading this amazing blog post By Mikayla Hutchinson, i realized that visual studio for mac is somehow similar to Xamarin studio but with the ability to build ASP.NET Core apps.

Note they all share the same functionalities such as the drag and drop support and build your interfaces.

Now in my series, I’m going to use Xamarin studio since am a mac user.

Enough talking about theoretical stuff, I like to get my hands dirty with C# code, so let’s get started and build our first Xamarin app. We will have a series of posts each post going to build part of the app till we end up with a good solid app.
Let’s get started 🎉
What are we going to build? (Part 0)