Realm database with Xamarin Forms

Realm database with Xamarin Forms

xamarinformsrealm1

Short introduction

Database in mobile app – sounds familiar? Of course! This element is crucial nowadays. Many applications require access to database and it is not only about offline access to data but also about performance. With Xamarin we can use SQLite database (also in cross platform way). It is really good approach but what about others?

In this article I would like to introduce Realm database and how to use it with Xamarin Forms application.

Realm data structure and access is show below:

realmdiagram

As you can see each objects derives from RealmObject. You can use LINQ to create queries.

Why should you try Realm?

  • It is fast
  • It is cross-platform
  • It is strongly supported by community
  • It is easy to use

 

What do I need to start?

1) Visual Studio 2015 Community (for free or choose higher version) or Xamarin Studio

UWP project will be supported soon (during writing this article UWP was not supported yet).

 

Let’s start

1. Create new Xamarin.Forms project (Portable with XAML):

xamarinformsrealm2

2. Your project structure should look like below:

xamarinformsrealm3

3.Now add NuGet package called “Realm”. Remember to add it to each project (so PCL, Android and iOS):

xamarinformsrealm4

xamarinformsrealm5

Rebuild project to see if everything is good.

 

Create simple UI with list of items

We will create simple list with objects – cars with pictures. Then we will connect Realm database to store list items in it.

1. Replace existing code in MainPage.xaml file with the one 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" xmlns:local="clr-namespace:RealXamarinFormsDemo" xmlns:converters="clr-namespace:RealXamarinFormsDemo.ValueConverters" x:Class="RealXamarinFormsDemo.MainPage">

  <ContentPage.Resources>
    <ResourceDictionary>
      <converters:StringToImageConverter x:Key="stringToImageConverter"></converters:StringToImageConverter>
    </ResourceDictionary>
  </ContentPage.Resources>

  <ListView ItemsSource="{Binding CarsCollection}" Margin="24">
    <ListView.ItemTemplate>
      <DataTemplate>
      <ImageCell Text="{Binding Brand}" ImageSource="{Binding Thumbnail, Converter={StaticResource stringToImageConverter}}" />
       </DataTemplate>
    </ListView.ItemTemplate>
  </ListView>

</ContentPage>

2. Now create “Model” folder in Portable project and add “Car” class to it:

xamarinformsrealm6_6

3. “Car” class should look like below:

 public class Car: RealmObject
    {
        public string Brand { get; set; }
        public string Thumbnail { get; set; }
    }

4. Now create “ValueConverters” folder and add “StringToImageConverter” class. It will be responsible for returning ImageSource from the file name:

  public class StringToImageConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            var filename = (string)value;
            return Device.OnPlatform(
                      iOS: ImageSource.FromFile("Images/" + filename),
                      Android: ImageSource.FromFile(filename),
                      WinPhone: ImageSource.FromFile("Images/" + filename));
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

xamarinformsrealm7

5. Now open “MainPage.xaml.cs” file and replace code with below:

public partial class MainPage : ContentPage
    {
        public ObservableCollection<Car> CarsCollection { get; set; }
        public MainPage()
        {
            InitializeComponent();

            LoadCars();
            if (CarsCollection == null)
                CreateCarsList();
            BindingContext = this;
        }

        private void LoadCars()
        {
            var realm = Realm.GetInstance();
            CarsCollection = realm.All<Car>() as ObservableCollection<Car>;
        }

        private void SaveCars()
        {
            var realm = Realm.GetInstance();
            realm.Write(() =>
            {
                foreach (var car in CarsCollection)
                {
                    realm.Add(car);
                }
            });
        }

        private void CreateCarsList()
        {
            CarsCollection = new ObservableCollection<Car>()
            {
                new Car()
                {
                    Brand = "BMW",
                    Thumbnail = "bmw.png"
               },
                new Car()
                {
                    Brand = "Audi",
                    Thumbnail = "audi.png"
               },
                new Car()
                {
                    Brand = "Mercedes",
                    Thumbnail = "mercedes.png"
               }
            };
            SaveCars();
        }
    }

Just for the demo purpose I decided to implement simple data flow. Once application is launched, Realm checks whether cars list was saved before. If not, new list is created and then saved in the database.

Remember to add images (feel free to select) to folder on each platform:

xamarinformsrealm9

 

Launch Android application:

Here you can see the result on Android platform:

xamarinformsrealm8

 

Launch iOS application:

Here you can see the result on iOS platform:

xamarinformsrealm10

 

Some important facts:

  • All changes to an object (addition, modification, and deletion) must be done within a write transaction
  • If you add at least one constructor to your class, make sure there is a public parameterless one as well
  • Realm supports primitive types except unsigned ones (bool, char, byte, short, int, long, float and double) as well as string, and DateTimeOffset. The nullable equivalents are supported as well
  • Realm Xamarin does not allow models to be further subclassed in any way. The weaver will fail if it detects a class that inherits indirectly from the RealmObject class

Sum up

Now you know alternative for SQLite for Xamarin platorm. This is only simple demo but you can find much more information in the official documentation. This sample application is available on my GitHub.. Have fun!

Advertisements