Adding a SQLite database to Xamarin.Forms

SQLite Logo
Source: Wikipedia (https://en.wikipedia.org/wiki/SQLite)

SQLite is an excellent choice for local storage within a mobile application. It is lightweight and with virtually zero configuration. Adding SQLite to a Xamarin.Forms project is fairly straightforward:

1. Add the nuget package SQLite-net PCL to each project (PCL, Android, & iOS)
Author = Frank A Krueger
ID = sqlite-net-pcl

2. Add an interface to the PCL project called: ISQLiteService.cs

3. Add a class to the iOS project called: SQLiteService.cs

4. Add a class to the Android project also called SQLiteService.cs

5. Add a class to the PCL project called: BaseItem.cs

6. Add a class to the PCL project called: Database.cs

7. To create a table model, simply create a class with public properties (with getters and setters) of the types and names of each field in the table. The class should inherit from BaseItem; this adds an auto incrementing ID field.

8. Create an instance of Database.cs called: database
To create a table simply call database.CreateTable();

Xamarin.Forms SQLiteExample ScreenshotYou now have a fully functioning database in Forms. To see a database in action, checkout out my example project on GitHub.

 

If you have any comments, questions, or suggestions, feel free to leave a comment below.

Creating a hamburger menu in Xamarin.Forms

Amazon Hamburger Menu
Source: Amazon iOS App (Amazon.com)

One of the most common navigation design patterns for applications and websites is none other than the hamburger menu. While the effectiveness of this type of navigation is greatly debated in the industry, no one can dispute that consumers have, for better or worse, acclimated to these menus. Many of the bigger players in the industry have utilized these menus within their applications (e.g. Amazon, Facebook, Google… to name a few).

Regardless of which side of the fence you are on, implementing a hamburger menu is dead simple in Forms. Xamarin has cleverly disguised their implementation as “Master-Detail Page.”

To create a hamburger menu:

1. Add a new class to your project called: MenuPage
2. Have MenuPage inherit from ContentPage
// TODO: Customize the MenuPage to your heart’s content (with navigation logic, Buttons, ListViews, Labels, etc).

3. Add a second new class to your project called: HomePage (call it whatever)
4. Have HomePage also inherit from ContentPage

5. Add a third new class to your project called: RootPage
6. Have the new class inherit from MasterDetailPage

7. In the constructor of App.xaml.cs, create a new instance of RootPage
8. Create a new instance of MenuPage
9. Assign MenuPage to the Master property of RootPage
10. In the same constructor, create a new instance of a NavigationPage, add a new instance of HomePage as the argument for the NavigationPage
11. Assign the instance of NavigationPage to the Detail property of RootPage

The NavigationPage becomes your navigation stack. Therefore, if you want to push a new page onto the stack (from your MenuPage), simply call:

App.NavigationPage.Navigation.PushAsync(PAGE)

Or pop a page off the stack (from your MenuPage):

App.NavigationPage.Navigation.PopAsync()

To replace the HomePage with another page:

Xamarin will automatically provide a hamburger menu button within your navigation bar. I have found the default navigation bar to be a royal pain to customize. My recommendation would be to implement your own custom header bar. If you do create a custom header, simply call RootPage.IsPresented = true; to open the menu drawer. Set it to false to close it.

// UPDATE: as requested, here is an example project

Enabling TLS 1.2 in Xamarin.Forms

For the life of me, I cannot understand why Transport Layer Security (TLS) 1.2 is not yet supported out of the box for Xamarin. According to Xamarin’s website, this is due to the fact that Mono still only supports TLS 1.0.

Xamarin has provided special handler’s that will leverage platform specific API’s that enable TLS 1.2; unfortunately, these handlers are not Portable Class Library (PCL) friendly and support only the most recent platform operating systems. I don’t know about you, but the mobile apps that I develop can’t be that picky in respect to the devices I support. I wish I only had to support the latest and greatest :p.

Fortunately, there is a simple solution that is both PCL friendly and can support older OS’s. This means that we can use this within a Xamarin.Forms solution.

  1. Right click packages (in the solution explorer)
  2. Click Add Packages…
  3. Search “ModernHttpClient”
  4. Find the following package: Id = modernhttpclient, Author = Paul Betts
  5. Add the package to EACH project package folder (PCL, Android, iOS,…)

// NOTE: ModernHttpClient has to be installed within each project due to how bait-and-switch libraries work.

Next, add the following packages to the PCL project:

  1. Id = Microsoft.Bcl, Author = Microsoft
  2. Id = Microsoft.Bcl.Build, Author = Microsoft
  3. Id = Microsoft.Net.Http, Author = Microsoft

You are now ready to start writing REST code. The secret behind ModernHttpClient is that it will use a bait-and-switch technique that will utilize the native platform handlers that support TLS 1.2. Simply use the following message handler: NativeMessageHandler().

Below is a rudimentary code sample without error handling (within the PCL):

 

Using Dependency Services with Xamarin.Forms

When developing with Xamarin.Forms, you will quickly find yourself in a situation where some of the native platforms’ functionalities were not implemented in the Forms API. In these situations, you can use the power of a Dependency Service to access the native Xamarin for each platform.

For example, say you want to access the devices’ GPS functionality. Each platform has GPS capabilities, yet function slightly differently. In a situation like this, using a dependency service will provide you access to all the native functionality on each platform within the shared code of the portable class library (PCL).

A dependency service is exactly what it sounds like. Within the PCL project, you will have a service (interface) that abstracts the functionality that you need access to in each platform. Within each platform project, you will create the native implementation that correlates with your shared abstraction.

Let’s go ahead and implement a simple dependency service. Forms does not provide access to your application’s cookie storage. While the cookie storage is handled automatically for WebViews and other network requests, you may need to access the cookies directly.

1. Within the PCL project, create an interface file called: INativeCookieService.cs

2. Add the methods and properties you are abstracting

3. Within the Android project, create a class called: NativeCookieService.cs

4. Add the assembly attribute:
[assembly: Dependency(typeof(MyCoolApp.Droid.NativeCookieService))]

5. Have the class implement: INativeCookieService

6. Add the native functionality

7. Repeat steps 3 – 6 for iOS (and Windows if you are supporting Windows). Make sure to use the iOS namespace rather than the Android on step 4

Whenever you need to use the native functionality within the PCL, you simply make the call:

What is a Custom Renderer?!

One of the most initially confusing, yet essential components to Xamarin.Forms are custom renderers. If you look at almost any advanced feature or customization tutorial for Forms, you are likely to run into the term custom renderer. But what the heck is a custom renderer?!? Everyone seems to reference the use of them, yet no one seems to take the time to thoroughly explain what they are and how they work.

Custom renderers are really simple once you understand the foundation behind how Forms renderers the user interface. Forms maps every UI element to each of the native platforms’ UI elements. In other words, Forms has generic views/controls that are referenced in XAML and are transformed into the native platforms equivalent view. For example, Forms has a Xamarin.Forms.Button class, which gets rendered to UIKit.UIButton on iOS, and android.widget.Button on Android. Essentially, a renderer is simply a mapping between a Forms element, and a platform’s native element. A custom renderer goes one step further; the developer, can override or extend Xamarin’s renderer.

Why would we ever want to change Xamarin’s default renderer? While Xamarin implements a majority of our UI/UX needs, we might need more granular control over the look or behavior of our views.

How do we create a custom renderer? A simple scenario (yet annoying) that requires the use of a custom renderer is when you want to prevent autocorrect on an Entry field when rendered on iOS. An Entry field is Forms’ version of a textbox. Unfortunately, by default on iOS, the textbox has autocorrection and first letter capitalization turned on, yet Forms does not provide a simple way to disable these settings. This is an example of a situation where a custom renderer is required to accomplish our goal.

Suppose you have a simple login page that uses an Entry field for the username and password:

Notice that we are using the default Entry tags in the LoginPage’s XAML. The magic does not happen within the portable class library (PCL); rather, all of our customization will be handled in each platforms’ native project.

  1. For this example, create a folder in the iOS project called: Renderers
  2. Within that new folder, create a new class called: CustomEntryRenderer
  3. Add the following line to the class before the namespace: [assembly: ExportRenderer(typeof(Entry), typeof(MyCoolApp.iOS.CustomEntryRenderer))]
  4. Have the class inherit from: EntryRenderer
  5. Override: OnElementChanged

Within a custom renderer class, there are two important properties to be aware of, Control and Element. The Control property refers to the platform’s native view. The Element is the Forms’ mapping to the Control. For this simple example, we only need to manipulate two settings on the native Control, AutocapitalizationType and AutocorrectionType.

Now, whenever we use an Entry element within our PCL project, this custom renderer will override the default iOS renderer due to the assembly reference we added before the namespace. One nice design aspect to note is that the our views are blissfully unaware of the custom renderer (i.e. they are loosely coupled). That also means that since we did not implement an Android custom renderer, Android will continue to use the default renderer.

Navigation using MVVM Light

MVVM Light is one of many free MVVM frameworks available today. As the name implies, MVVM Light is a lightweight framework that allows the developer to utilize as much or as little of the framework as is needed.

Conversely, other MVVM frameworks are more of an “all or nothing” design. The problem with the “all or nothing” design is that they essentially replace the base system that you are developing on. For instance, if you are developing with Xamarn.Forms, and you adopt one of beefier MVVM frameworks, the framework will completely override a large percentage of how Forms was intended to operate. This can cause major frustration when reading blogs, tutorials, and other coding examples.

As we discussed in the previous post, Forms utilizes XAML for UI implementations and thus is intended to follow the MVVM design pattern. That being said, a large percentage of Xamarin developers (including myself) agree that Forms does not by default correctly handle navigation using the MVVM pattern because the Views dictate the navigation logic not the ViewModels.

For anyone that is just starting out with Forms, navigation can be very frustrating. Fortunately, there is an easy solution to move navigation logic from the Views to the ViewModels using MVVM Light.

We first need to add the MVVM Light package to each project in our solution (PCL, Android, iOS, and any flavor of Windows that you are supporting).

  1. Right click Packages in the solution explorer
  2. Click Add Packages
  3. Use NuGet’s search function to find MVVM Light libraries only package (Id: MvvmLightLibs, Author: Laurent Bugnion (GalaSoft))
  4. Add Package (to each project)

MVVM Light will add the dependency CommonServiceLocator package by Microsoft. Before we implement our navigation service, we need a way to globally access this service so that all ViewModels have access. This is where the Locator comes into play.

In the PCL project, create a folder called Services. Within the Services folder create a class called Locator. We only want one Locator for the entire application, so we will follow the singleton pattern and make the Locator constructor static.

There are three main components to this class, the string constants at the top, the constructor, and various properties with getters. The constants act as keys for each page registered for the navigation service. The constructor handles all the registration of services and ViewModels; ViewModels do not have to be created within the locator, they can be instantiated by the view. Finally we expose the Navigation Service and ViewModel instances with property getters.

Next, let’s implement the NavigationService. In the same folder as the Locator, create a class called NavigationService. This class will implement the MVVM Light (GalaSoft) INavigationService interface. Add the following methods and properties:

At this point, we still do not have a globally accessible NavigationService. Open the class code-behind that implements Application; this is usually called App.xaml.cs. Add the following locator property:

Our ViewModels are now able to completely handle our navigation logic using App.Locator.NavigationService.NavigateTo(PAGE KEY).

Example:  App.Locator.NavigationService.NavigateTo(Locator.SecondPage);

This tutorial is based off of Mark’s Blog.

Xamarin.Forms, MVVM, and Navigation

Coming from a Xamarin native background, I was not entirely familiar with the MVVM pattern prior to switching to Xamarin.Forms. The native designs for iOS and Android typically follow the MVC pattern. MVVM was designed by Microsoft specifically for applications that utilize XAML to design their UIs. If you are familiar with MVC, MVVM is not wildly different. MVVM stands for Model-View-ViewModel.

MVVM Pattern
Source: Microsoft.com

A very rudimentary way to describe MVVM is that you have your typical data models which make up the Model part of the acronym. These data models represent the objects and business logic within your application. Next, we have the View; this is exactly what it sounds like, essentially everything that is rendered on the screen is part of the View.  The ViewModel is the unique (or not so unique) aspect of the pattern. This is where all of your view logic and states are handled. Additionally, the ViewModels act as the middleman between the Views and the Models.

The main objective to using the MVVM pattern is to create loosely coupled code between the Views and the ViewModels. In other words, the Views know about the ViewModels; however, the ViewModels should not know about the Views. Additionally, the Views should not know about the (data) Models and the Models should not know about the Views, or the ViewModels. The purpose behind such a design allows developers to quickly and easily swap out Views with other Views without having to change the business and application logical. Furthermore, this design allows separate teams to work on different components of the project. For example, on a large team, designers could work on the Views of the application (in XAML without any other programming knowledge), while developers could handle the ViewModels, and Models.

Xamarin.Forms was designed with MVVM in mind due to the adoption of XAML. Most of the framework has implemented the tools necessary to utilize the MVVM pattern. However, in my opinion (and the opinion of others) one aspect of the framework design completely breaks the MVVM pattern, and that is navigation.

Xamarin.Forms handles navigation using the INavigation interface available on any Page type (aka the Views). INavigation acts as a globally available navigation stack for your entire application. You might be thinking, that’s great, what’s the problem? The main problem, is that the Views are in charge of handling navigation, not the ViewModels. This technically breaks the MVVM pattern because the Views are dictating how your application operates, not the ViewModels. Under this design, it becomes very difficult to replace a particular View without fixing the logical structure of your application.

So what’s the solution? The solution is to move all of your navigation logic into your ViewModels. In my next post, I will go into detail of how to do this using a framework called MVVM Light.

Custom App Header in Forms

iOS Navigation Bar NestedIt is safe to assume that any business with a customer facing application will want to brand their application with at least their logo. From the very onset of using Xamarin.Forms, I found myself annoyed with the lack of customizability of the navigation bar for iOS. To be fair, it is a pain to customize on the native side; however, the Forms’ abstraction removes most of your options.

NOTE: the navigation bar shows up when a Page is nested within a NavigationPage; this creates a navigation stack.

The equivalent implementation for Android is a toolbar or action bar. Within the Android project, you can customize the toolbar using the native Toolbar.axml layout file. Unfortunately, in order to customize the iOS navigation bar to the same extent as Android requires a custom renderer and a fair amount of hacking. Even with the ability to manipulate the look of the iOS navigation bar using a custom renderer, both platforms are now diverging from each other (not to mention if you support Windows). This messy solution wasn’t going to work for me. Two simple features resolved this dilemma.

I came to the realization that I could not use the navigation bar (iOS) or toolbar (Android) and maintain a unified solution between platforms. Simply put, I wanted the platform specific bars to disappear. Thankfully, Xamarin provides a simple way to turn them off. Using the static reference to NavigationPage provides the method SetHasNavigationBar. This method takes two parameters, the page the setting applies to and the boolean value.

At this point my navigation stack no longer has a header. This allows me to add a completely custom implementation that will work for all platforms. An easy way to create such a header is with the combination of a boxview, a back button, and a logo. The specifics are not important because it will vary greatly between applications. An example could look like the following:

But how do I apply this XAML to each of my pages?! This can be accomplished with a ControlTemplate. A ControlTemplate is a UI template that can be applied to any XAML page. You’ll define the template in the ResourceDictionary located in the App.xaml file. You will also include a ContentPresenter within the template. A ContentPresenter is the content area or body of the pages the template is being applied to. The ControlTemplate Key will be used to reference the template in your pages.

Once the ControlTemplate is created, we need to apply it to our Pages. This is accomplished by adding a StaticResource reference of the template Key inside our pages’ ControlTemplate property in the XAML.

iOS Custom App HeaderYou now have a fully customizable header for your application. You can add EventHandlers, Commands, or GestureRecognizers to interact with your header as needed. You will have to implement the back button logic as well.

Creating Xamarin.Forms Solution

In this post, we will see how to create a simple Xamarin.Forms application. We will be using Xamarin Studio as our IDE of choice; the initial setup is almost identical using Visual Studio. There is one cavate when determining your developer environment, Mac OS X is required to compile iOS applications and Windows is required to compile Windows applications (thanks Google for playing nice). In a later blog post, I will cover how to add a Windows application to an existing project created on Mac OS X using a Windows virtual machine.

To get started, first open Xamarin Studio on a Mac. From the menu bar, select File > New > Solution. The following dialog will appear. This dialog will allow you to select which project template to use for your solution. Select Multiplatform > App > Forms App and then click Next.

Xamarin Studio New Solution Choose A Template

You will then see another dialog to configure the main settings for your Forms App.

In the App Name textfield, put the name of your application. If the name of the application is more than one word,  Xamarin Studio will add dashes to the complete package name. This can have unintended consequences later on when using advanced features such as intent filtering. My recommendation is to not add any spaces using this dialog and we will fix the display name after the solution has been created (iOS: Open Info.plist > Update Application Name textfield to the desired display name | Android: Right Click on Android Project > Select Android Application > Update Application Name textfield to the desired display name).

In the next textfield, type your organization’s identifier such as a company name. It is customary to prefix the name of your organization with “com.”; the organization identifier and app name will be concatenated to make your applications’ package name (e.g. com.MyCompany.HelloForms).

Next, select which platforms you intend to target. Notice that only Android and iOS are available, this is due to the fact that we are using a Mac. We will add Windows to the solution in a later blog post.

Under the Shared Code section you have the option between using a Portable Class Library (PCL) or a Shared Library. There are pros and cons to using either option. For this example, we will use a PCL since it is the simplest of the two and is the preferred method.

Lastly, you will have the option to use XAML for building your User Interface (UI). This option does not prevent you from using C# to create some or even all your views, it simply indicates your preference. If you are not familiar with XAML, it stands for Extensible Application Markup Language and is an XML based language used to create UIs. XAML is not unique to Xamarin; Microsoft actually developed it and is used with a multitude of technologies such as SilverLight and WPF. For this demo, leave XAML left checked. Then click Next.

Xamarin Studio New Solution Configure Your Forms App

In the final dialog, you will configure your main project settings.

In the Project Name textfield, put the name of your application. This will be used as the name of your PCL project and the prefix to your Android and iOS projects (e.g. HelloForms.Droid and HelloForms.iOS).

In the Solution Name textfield, put the name of your solution. This does not have to match your project name.

Location indicates where on the file system your new solution will be located.

Version Control instantiates a local git repository inside the solution directory. We will not be using git for this demo.

Leave Xamarin Test Cloud unchecked for this demo. Click Next.

Xamarin Studio New Solution Configure Project

We now have a fully functioning application. In the next blog post, we will go over the structure of the solution in detail.

Switching to Xamarin.Forms?

After attending Xamarin Evolve16 this year, Xamarin.Forms appears to have significantly matured since its introduction two years ago. Having only developed using Xamarin.iOS and Xamarin.Android, I had limited exposure to Forms prior to the conference. While at the conference during trainings and conference sessions, it became clear that Xamarin is really pushing the adoption of Forms.

So the question becomes, what is Forms and should I use it? The main business case for using Xamarin is the ability to share as much code between platforms as possible. Xamarin native allows developers to share a majority of their business logic and models, yet you are still stuck having to write a UI for each platform. The most simplistic way I can describe Forms is that it is Xamarin’s attempt to abstract the UI for extensive code sharing and still deliver native (or nearly native) performance and design. Xamarin claims that they were able to share more than 90% of the code for their 2016 Evolve app between Android, iOS, and Windows.

Xamarin Evolve 2016 Android App Code SharingXamarin Evolve 2016 iOS App Code Sharing Xamarin Evolve 2016 Windows App Code Sharing

Images Source

My first impression to this claim was, this sounds too good to be true, so what’s the catch? The catch to using Forms, is that you “lose” the granular control over your UI and the simplicity of platform specific APIs. My previous statement must be qualified because it is not entirely accurate. Before I can explain further, I first have to explain the structure of a Forms application.

Xamarin Forms PCL Solution StructureA Forms solution contains a project for each platform you intend to target. Therefore, you will have a project for Android, iOS, and each flavor of Windows that you decide to support. Also within the solution, you will have an additional project called the PCL or portable class library. Think of the PCL as the core of your application where a majority of all your code lives. Inside the PCL is the Xamarin.Forms NuGet package, which contains all the required libraries to build a Forms application. The primary difference between a native Xamarin app and a Forms app is the PCL. In other words, a Forms app is exactly the same as a native Xamarin app but with additional libraries. This technically means you have access to all the native Xamarin APIs as before (with a catch).

With a rudimentary understanding of the Forms structure, I can now explain my original claim about losing some native control. Since the purpose of using Forms to build your application is to maximize code sharing, this creates complexities when you need to access platform specific features or complete control over your design. While I technically have access to all the native Xamarin APIs, I have to jump through additional hoops in order to utilize them.

The two main approaches to access the native APIs are to use either a custom renderer or a dependency service. A custom renderer allows you to create native UI elements (such as a UIKit.UIView in iOS or a Android.Views.View in Android) for each platform and then integrate them back into a Forms page or view.  A dependency service allows you to access device specific functionality such as the built-in cameras or GPS.

If we have access to all the native APIs, why don’t we always build Xamarin apps using Forms? Two significant reasons why you should weigh your options before making a decision are performance and path of least resistance. Performance is a factor because the entire UI in a Forms application is a compilation of custom renderers contained within the Xamarin.Forms package. This means that there is an additional performance cost to rendering your views. If your application is graphics intensive or uses a large amount of memory, the end users might notice your application not working smoothly. The path of least resistance comes into play depending on the complexity of your application. If your application requires access to a large amount of the native platform APIs and has significant custom UI needs, you will be spending as much if not more time writing custom renders and dependency services as you were attempting to save by sharing more code between platforms. On the other hand, if it is more important to share code between platforms than direct access to the native APIs, Forms is a strong contender. Xamarin provides a quick one page PDF to help you decide which camp your app falls into.

Over the next few months, I will be writing about my experience of porting existing Xamarin.Android and Xamarin.iOS eCommerce apps over to Xamarin.Forms. After evaluating and testing Forms, my team feels that we could benefit from the adoption of Forms. We believe our existing apps fall under the 80/20 rule, 80% of our apps require very little advance custom UIs and platform specific features, while 20% does. Our hope is that the 80% saves us more development time than the 20% of additional overhead. I hope my experience will help others make the right decision for their apps.